From: trans Date: 2009-06-19T20:53:56+09:00 Subject: Re: each by arity On Jun 19, 4:57 am, Robert Dober wrote: > On Fri, Jun 19, 2009 at 8:35 AM, Robert > > Klemme wrote: > > 2009/6/19 trans : > > >> Perhaps, but I must think about it some more. Presently one would do > >> (in 1.9): > > >>  coll.each_slice(n){ ... } > >>  coll.each_cons(n){ ... } > > No It would be >    coll.each_cons # this is the proxy, it does not know about the slice size yet >      .map{ |a,b|  ... }  # the proxy will look at the arity. > > > > > > >> If one wanted to map over that: > > >>  coll.map.each_slice(n){ ... } > >>  coll.map.each_cons(n){ ... } > > >> correct? > > > For mapping in 1.9 I would do > > > coll.each_slice(n).map{ ... } > > coll.each_cons(n).map{ ... } > > >> So how do we best achieve "by arity" without stepping on present toes? > > > I would simply stick with the existing behavior. :-) > > I will not let the absence of use cases let ruin my work ;) Now I have > always liked Tom's reach for perfection, but on a practical base I > agree with Robert it is probably not worth it. :) Robert... someone understands me! > But on a theoretical ground I find it intriguing that the "proxy" > would do something similar to what an enumerator does. > An enumerator prepares a view of an enumerable for an actual method > delivering the behavior in a block. > One could say it "waits" for a message with a block. > The proxy will wait for a message too, and a block too, and will just > create the Enumerator on the fly with the information of the arity. > I even wonder if Enumerator could be the proxy with a little monkey > patch? And that might as well lead to a "default" behavior for map, > without the "proxy method" which would meet Tom's original requirement > for Enumerators *only* > > Thus  [1,2,3].map{|a,b| [a,b]} would still be [[1, nil]....] > *but* > [1,2,3].to_enum.map{|a,b| [a,b]} would be [[1,2],[3,nil]] Though I think that would be kind of confusing, if not problematic. As others have pointed out there is no way to query the parenthetical patterns, eg. |(a,b)| so this will be somewhat more limited but I was thinking of something like: [1,2,3].each.by_arity{ |a,b| ... } or conversely [1,2,3].by_arity.each{ |a,b| ... } But we'd still need a way to do #each_cons by arity. To do this I think there would need to be an equivalence. #each_slice is to #each as #each_cons is to ___ ? So we define a method #cons that normally means each_cons(1). Then... [1,2,3].cons.by_arity{ |a,b| ... } or conversely [1,2,3].by_arity.cons{ |a,b| ... } Though honestly this makes me wonder why #each just doesn take an optional slice number -- why have a completely separate method for the special case of n=1, when an optional argument would do? Indeed Facets has #each_by that does this. P.S. I am half tempted to alias #each_by as #air, as in "air your arguments", and then name the cons version #conair ;) T.