Delegate attribute methods to the parent object
delegation, ruby
Solution
You can use `Forwardable` (it is included in the Ruby standard library):
require 'forwardable'
class Alphabet
extend Forwardable
def_delegators :@alphabet, :[], :include?
def initialize
@alphabet = ('A'..'Z').to_a
end
end
foo = Alphabet.new
p foo[0] #=> "A"
p foo.include? 'ç' #=> false
If you wish to delegate all the methods not defined by your class you can use `SimpleDelegator` (also in the standard library); it lets you delegate all the methods that are not responded by the instance to an object specified by `__setobj__`:
require 'delegate'
class Alphabet < SimpleDelegator
def initialize
@alphabet = ('A'..'Z').to_a
__setobj__(@alphabet)
end
def index
'This is not @alphabet.index'
end
end
foo = Alphabet.new
p foo[0] #=> "A"
p foo.include? 'ç' #=> false
p foo.index #=> "This is not @alphabet.index"
When the delegate doesn't need to be dynamic you can arrange the master class to be a subclass of `DelegateClass`, passing the name of the class to be delegated as argument and calling `super` passing the object to be delegated in the `#initialize` method of the master class:
class Alphabet < DelegateClass(Array)
def initialize
@alphabet = ('A'..'Z').to_a
super(@alphabet)
end
More info about the delegation design pattern in Ruby here
Problem
I have the following class: ``` class Alphabet attr_reader :letter_freqs, :statistic_letter def initialize(lang) @lang = lang case lang when :en @alphabet = ('A'..'Z').to_a @letter_freqs = { ... } when :ru @alphabet = ('А'..'Я').to_a.insert(6, 'Ё') @letter_freqs = { ... } ... end @statistic_letter = @letter_freqs.max_by { |k, v| v }[0] end end foo = Alphabet.new(:en) ``` The central member here is `@alphabet`. I'd like to make it some sort of a container class to invoke Array methods directly like ``` foo[i] foo.include? ``` instead of explicitly accessing `@alphabet`: ``` foo.alphabet[i] foo.alphabet.include? ``` I know I could define a lot of methods like ``` def [](i) @alphabet[i] end ``` but I'm looking for a proper way of "inheriting" them.