The Forwardable module provides delegation of specified methods to a designated object, using the methods def_delegator and def_delegators.
For example, say you have a class RecordCollection which contains an array
@records. You could provide the lookup method
record_number(), which simply calls #[] on the @records array,
like this:
class RecordCollection extend Forwardable def_delegator :@records, :[], :record_number end
Further, if you wish to provide the methods size, #<<, and map, all of which delegate to @records, this is how you can do it:
class RecordCollection # extend Forwardable, but we did that above def_delegators :@records, :size, :<<, :map end f = Foo.new f.printf ... f.gets f.content_at(1)
Also see the example at forwardable.rb.
Define method as delegator instance method with an optional
alias name ali. Method calls to ali will be
delegated to accessor.method.
class MyQueue extend Forwardable attr_reader :queue def initialize @queue = [] end def_delegator :@queue, :push, :mypush end q = MyQueue.new q.mypush 42 q.queue #=> [42] q.push 23 #=> NoMethodError
# File rake/lib/forwardable.rb, line 197 def def_instance_delegator(accessor, method, ali = method) line_no = __LINE__; str = %Q{ def #{ali}(*args, &block) begin #{accessor}.__send__(:#{method}, *args, &block) rescue Exception [email protected]_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug ::Kernel::raise end end } # If it's not a class or module, it's an instance begin module_eval(str, __FILE__, line_no) rescue instance_eval(str, __FILE__, line_no) end end
Shortcut for defining multiple delegator methods, but with no provision for using a different name. The following two code samples have the same effect:
def_delegators :@records, :size, :<<, :map def_delegator :@records, :size def_delegator :@records, :<< def_delegator :@records, :map
# File rake/lib/forwardable.rb, line 170 def def_instance_delegators(accessor, *methods) methods.delete("__send__") methods.delete("__id__") for method in methods def_instance_delegator(accessor, method) end end
Takes a hash as its argument. The key is a symbol or an array of symbols. These symbols correspond to method names. The value is the accessor to which the methods will be delegated.
# File rake/lib/forwardable.rb, line 150 def instance_delegate(hash) hash.each{ |methods, accessor| methods = [methods] unless methods.respond_to?(:each) methods.each{ |method| def_instance_delegator(accessor, method) } } end