From: Judson Lester Date: 2002-10-23T06:38:54+09:00 Subject: Re: Duck patterns in Ruby On Sunday 20 October 2002 07:52 pm, MikkelFJ wrote: > I was just thinking about a problem, and I happened to be pseudo coding > partially in Ruby, partially something else. Then I figured the pseudo code > might be useful Ruby. > > In Ruby you can use case / when to branch you code based on object type. > But it's generally not seen as good style to branch on type in Ruby, > because it violates the duck typing principle. (If it quacks its a duck). > > But in line with Ruby's duck typing why not add some duck matching: > > My original problem involved getting arguments in that was either a > collection or a single item, for example a generic product method. So I > thought it would be nice to be able to branch the code based on whether an > argument had the "each" method. This lead to the idea of a kind of pattern > matching based on available methods instead of the more strict matching on > a class. > > def product (x, y) > p = 0 > match_methods(x, y) > when(:each, nil) x.each {|a| p = p + a.multiply(y) } > when(nil, :each) y.each {|b| p = p + x.multiply(b) } > when(nil, nil) p = x.multiply(y) > end > return p > end > > (Might also be nice to branch based on whether a method yields or takes a > code block as argument). Why not define a class whose === operator is true for objects that have certain methods - or even check arity - possibly even bind the specific method and toss give it a proc that raises an exception to test to yielding. Then you can just us the DuckIdentity class in a case block - no need for new constructs, and DuckIdentity can be enhanced with things like attribute stuff... -- Judson