Delegation vs. Duck Typing (was Re: The Case for Multiple-Inheritance)

On Oct 6, 2007, at 7:48 PM, Jason P. wrote:

(The one sticking point I would occasionally hit was delegation, as
[offlist]

I’m enjoying this thread. Would you please consider elaborating on
this notion in the thread itself?

Sure, I’ll try.

For the record though, the issues I’m about to discuss don’t seem to
relate to Sylvain’s complaints about a lack of MI. For that reason,
I’ve renamed this subthread.

Delegation is a form of composition, like inheritance. The design
patterns movement has pushed that delegation is is more flexible to
inheritance and should be preferred when we are designing objects.

It comes in many, many forms but one example might be that we want a
strict Queue object. We want to allow enqueueing and dequeuing items
and peeking at the top item, but we don’t want users accessing items
in the middle of the Queue. One way to create this is to delegate
the needed operations to an Array:

require “forwardable”

class Queue
def initialize
@queue = Array.new
end

extend Forwardable

def_delegators :@queue, :shift, :<<
alias_method :enqueue, :<<
alias_method :dequeue, :shift

def peek
@queue.first # don’t delegate because it allows: first(n)
end
end

if FILE == $PROGRAM_NAME
q = Queue.new
%w[one two three].each { |num| q.enqueue num }
4.times { p q.dequeue }
end

END

Duck typing is a concept that says we should view the type of an
object by what it can do, more than what it is. The deeper you go
with this line of thought you generally come to realize than type
checking can often be avoided and leads to more powerful code when it
is. For example, an add_event() method could work with an Array, our
new Queue, or something else entirely:

$ irb -r queue

def add_event(event_list)
event_list << :event
end
=> nil

add_event(Array.new)
=> [:event]

q = Queue.new
=> #Queue:0x14f6ce8

add_event(q)
=> [:event]

q.peek
=> :event

This are simplified explanations, but hopefully the begin to
illustrate the differences.

James Edward G. II

On Oct 7, 2007, at 1:04 PM, James Edward G. II wrote:

Sure, I’ll try.

Thanks very much for taking the time to elaborate! There seems to be
two libraries for delegation in Ruby: forwardable and delegator. Is
one preferred over the other?

On Oct 7, 2007, at 5:00 PM, Jason P. wrote:

On Oct 7, 2007, at 1:04 PM, James Edward G. II wrote:

Sure, I’ll try.

Thanks very much for taking the time to elaborate! There seems to
be two libraries for delegation in Ruby: forwardable and delegator.
Is one preferred over the other?

Use delegator when you want to forward the entire interface of an
object and forwardable when you want to handle delegation method by
method. Also, remember that neither are needed in some cases. Ruby
is so dynamic it makes tasks like this quite easy.

James Edward G. II

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs