From: netghost@... Date: 2005-06-15T02:10:32+09:00 Subject: Re: duck-typing allows deeper polymorphism I was thinking perhaps you can define your duck types, ie: READABLE = [:open, :read] SORTABLE = ['<=>'.to_sym] Then extend Object a little: class Object def implements?(symbols) symbols.all?{|s| respond_to? s} end end It makes your types easily documented, and it's trivial to test if something implements the needed functionality. "hello".implements? SORTABLE => true "hello".implements? READABLE => false I'm not really a big fan of this style, but it might be handy to someone ;) .adam sanderson Eric Mahurin wrote: > I've seen many posts on what duck-typing is, that Ruby doesn't > need static typing, that duck-typing results in easy to read > code, etc (and others that want static typing). What I haven't > seen much of is what advantage duck-typing gives to a method > over conventional polymorphism. This is a follow on of my > previous thread "making a duck". I would like to get on my > soapbox and talk about it a little... > > With the polymorphism of other languages, class hierarchy is > very important. When you specify an argument can take a > certain class, you are saying that it can also take anything > derived from it (or implementing the same interface if the > language has that concept). > > With duck-typing, class hierarchy and class names are not > important. Every argument that is duck-typed (built-in methods > unfortunately usually aren't) effectively has its own "type". > The "type" of an argument is defined by what methods it needs > to respond to and any "type" requirements of those methods > arguments or return values. If an argument has no method > requirements, then that argument could be anything. With an > argument needs to respond to just one method, you can think > about making an object on-the-fly that meets that one > requirement. That one method could easily be made from a > method of another object - including Proc#call (arbitrary > code). With an argument that needs to respond to more methods, > you can still do the same (mapping multiple methods), but at a > certain point it may become too cumbersome. > > As an example, suppose you have 2 methods in an object that > take String-like things. With conventional polymorphism, you > might abstract this up to anything indexable to encompass > String and Array. With duck typing, you don't need to do > anything explicit - just continue thinking of it like a String > when coding the methods. Let's say one of the methods reads > from its "String" argument using only the [] method. You could > easily use a String, Array, Hash, or more powerfully a Proc. > The second appends to its "String" argument using the << > method. Here you could easily use a String or Array. In both > of these cases, you could grab any method of any object and map > it to new object (and name the method appropriately). Of > course the most flexible would be mapping a Proc#call - do > whatever you want in that Proc. > > To get maximum benefit from duck-typing, several things will > help out: > > * For every duck-typed argument, document what the duck-type is > - what methods it needs to respond to and what the duck-type > requirements are on those method arguments and return values. > To help out with this it would be nice if we had something in > rdoc for this - but I don't know what. > > * A convenient way to create objects on-the-fly for duck-typed > arguments. Some implementations were given in the thread > "making a duck". > > * Don't overload your methods. As soon as you overload a > method to allow multiple "types" for an argument (and do > different things based on the "type"), you are not doing strict > duck-typing. At a minimum when you overload, you have to ask > whether an object responds to a certain method to determine > what to do. Doing this can limit what you can pass in due to > ambiguities as to what the "type" is. If you make a method > that can take a flying-thing, a swimming-thing, or a > walking-thing, what should this method do when it receives a > duck - because a duck can fly, swim, and walk? > > * The fewer methods that a duck-typed argument responds to the > more flexibility you have in what you can pass to to it. Many > arguments may just require one method of the argument which is > ideal (next to zero methods of course). One method allows easy > on-the-fly object creation as described above. > > * Use duck-typing everywhere! > > > > __________________________________ > Discover Yahoo! > Have fun online with music videos, cool games, IM and more. Check it out! > http://discover.yahoo.com/online.html