From: ara.t.howard@... Date: 2006-12-14T04:44:04+09:00 Subject: Re: map taking an argument (was: Re: join_with) On Thu, 14 Dec 2006 dblack@wobblini.net wrote: >> i think that makes good sense considering ruby's pattern of not >> auto-magically munge aruements: we all agree that it's a good thing >> that this does not work >> >> "40" + 2 >> >> the e.map(:m) is exactly the equivalent of that: it says "by the >> way, if you pass me a symbol object i'll auto-magically convert that >> to a method call on the object. > > I don't see a similarity. in both cases the arguments types changes the semantics of the method. in one case a number is numged into a string. in the other a symbol is munged into a method/proc. in both cases this behaviour is burried in the method and users of the methods must know that passing certain classes of objects results in different behaviour. consider this pattern applied to more methods that take blocks but currently no arguments - can we always make the meaning the same? > It's not a conversion to a method; you couldn't replace the symbol with a > method object. harp: > cat a.rb class String def up(*a) upcase end end s = 'forty-two' p( [s].map(&:up) ) p( [s].map(&s.method(:up)) ) harp: > ruby19 a.rb ["FORTY-TWO"] ["FORTY-TWO"] > It's just a decision to have the argument have that meaning. > It may even be more circuitous, in a sense, than converting 2 to a string, > but I don't think it's the same at all. it's not __just__ having the argument have a meaning, it's having a particular class of object specify block auto-creation when it was originally nil. the indirection isn't extensible to other methods, transparent, or orthongonal. for instance, what does this do? enum.map(:upcase){|e| e.downcase} # noop it could throw an error - but why should it? we could simply have rule that the two blocks, the implied and the actual, are always run in a given order, say left to right. once we're there, we take the step that multiple args be given and that they too will be called left to right... enum.map(:upcase, :downcase){|e| e.upcase} # not noop now, the impl of map is very useful and yet the code is more complex, next we can tackle #each, then we can move on to each and every method that takes a block but takes no args. each one can have similar, or differnt behaviour based on extra symbol args. blocks that take multiple args will really complicate the rules. then we can doccument them.... yuk! this is what's known as code acretion and it's a __bad_thing__. __or__ we can write Symbol#to_proc __once__. doccument it __once__, and every single method in ruby, stdlibs, and user code can now leverage this functionality to compactly specified a block of {|elem| elem.send :meth} as simply &:meth. you can't really think the former is a better course of action do you? >> >> given that this will work all over the place, it's doubtfull that it >> will be more obsure than a special case for map, since people will >> use the idiom all over the place. > > Maybe that's what I'm afraid of. I find it obscure and ugly. well, that's hard to argue about. ;-) still, there are alot of ugly syntax elements in ruby like class << self and @@ugly and *list and self.a = :value still. we can just call these 'beauty marks' can't we? ;-) -a -- if you find yourself slandering anybody, first imagine that your mouth is filled with excrement. it will break you of the habit quickly enough. - the dalai lama