Hi –
From: dblack@superlink.net [mailto:dblack@superlink.net]
Sent: Thursday, August 07, 2003 6:41 PM
To: ruby-talk@ruby-lang.org
Subject: Re: Ducktype, right?
This is sort of like having a discovered mixin. Neat.
^^^^^^^^^^^^^^^^^^
Intriguing phrase. What do you mean exactly? 
From my days as a LISP programmer, we could create objects at will just by
mixing in (thus, mixin) named capabilities. This would be done explicitly.
Example:
;;;in CLOS/LISP
(defclass my-animal-robot (basic-robot
house-cleaner-mixin
duck-mixin)
(… now my robot-duck can clean the house …))
;;;;
So it’s sort of like multiple inheritance, but when I was doing LISP it was
much looser than ‘inheritance’. You just tossed it in there. But still, it
was defined previously.
As you probably know, Ruby also has mixins:
def talk
puts "quack"
end
end
class A
include M # mixin
end
A.new.talk # => quack
and you can even extend the capabilities of a single object this
way:
module MM
def walk
puts “waddling…”
end
end
duck = A.new
duck.extend(MM)
duck.walk # => waddling
A.new.walk # unknown method error (this A object can’t walk)
So, to answer your question. I’m just saying it’s a neat idea that I could
check ANY object to see if (discover) that the object has this capability
(kindof like a mixin) solely based on it’s operations, as opposed to its
having been formally defined that way.
in Ruby
yourRobot.quack if ducktype(yourRobot, duckness)
duckHerder.buy(myRobot) if ducktype(myRobot, duckness)
(I’m not sure I’d file the second example under “duck typing”
(since it’s argument-checking rather than object capability
checking), but you could probably come up with a method name
that was a superset of both 
You could also just do:
your_robot.quack if your_robot.respond.to?(“quack”)
(i.e., an unmediated test of the object’s capabilities at exactly the
moment when you want those capabilities), or, if you have a lot of
nanoseconds to spare:
begin
your_robot.quack
rescue NameError
your_robot.bark
etc.
end
The thing that bothers me about the explicit respond_to? test is the need
to type everything twice. But I’ve never come up with a way around that,
except the exception-raising one which is a lot slower. It also might
catch the wrong exception… for instance if you have:
def quack
100.blah # no such method
end
David
···
On Fri, 8 Aug 2003, Mills Thomas (app1tam) wrote:
-----Original Message-----
–
David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav