Hi -- On Fri, 8 Aug 2003, Mills Thomas (app1tam) wrote: > > -----Original Message----- > > 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 -- David Alan Black home: dblack / superlink.net work: blackdav / shu.edu Web: http://pirate.shu.edu/~blackdav