Version of forwardable.rb
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,
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)
If the object isn't a Module and Class, You can too extend Forwardable module.
printer = String.new printer.extend Forwardable # prepare object for delegation printer.def_delegator "STDOUT", "puts" # add delegation for STDOUT.puts() printer.puts "Howdy!"
Another example
We want to rely on what has come before obviously, but with delegation we can take just the methods we need and even rename them as appropriate. In many cases this is preferable to inheritance, which gives us the entire old interface, even if much of it isn't needed.
class Queue extend Forwardable def initialize @q = [ ] # prepare delegate object end # setup preferred interface, enq() and deq()... def_delegator :@q, :push, :enq def_delegator :@q, :shift, :deq # support some general Array methods that fit Queues well def_delegators :@q, :clear, :first, :push, :shift, :size end q = Queue.new q.enq 1, 2, 3, 4, 5 q.push 6 q.shift # => 1 while q.size > 0 puts q.deq end q.enq "Ruby", "Perl", "Python" puts q.first q.clear puts q.first
This should output:
2 3 4 5 6 Ruby nil
Notes
Be advised, RDoc will not detect delegated methods.
forwardable.rb
provides single-method delegation via the #def_delegator and #def_delegators
methods. For full-class delegation via DelegateClass, see
delegate.rb
.