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