On 6/21/07, Trans <transfire / gmail.com> wrote: > > > On Jun 21, 9:12 am, "Robert Dober" <robert.do... / gmail.com> wrote: > > On 6/21/07, Alexander Presber <aljos... / weisshuhn.de> wrote: > > > > > There should be a reason Enumerable was introduced as opposed to > > > include it's functionality in Array? > > > > Alexander I agree with your POV, however maybe it would do this > > discussion some good to take one step back and look at the greater > > picture. > > > > Enumerable is a Mixin based on each and it implements methods like > > select, map etc by using the each interface of it's client class. It > > very often returns arrays than as it simply cannot do something > > different - without creating a revolutionary new concept like an > > Iterator but that is OffTopic > > > > You were complaining about Hash#select returning an Array. I complain > > about that too but it has nothing to do with Enumerable, Enumerable is > > not used, it is implemented in Hash itself. > > > > If we want to discuss if we like or dislike Hash#select returning an > > array we shall fear to mention Enumerable as it has nothing to do with > > it. > > As a matter of fact it would be ridiculous - you have explained that > > nicely yourself - to ask Enumerable to return Hashes. > > > > Cheers > > Robert > > I can think of two potential solutions to this issue. Either require a > method in the enumerated class that dictates how to construct elements > of that class when enumerated (#<< might do), or we could have two > separate sets of enumerable methods, one for array elements and one > for hash key-value pairs. > > In the first case: > > (Note: I'm not testing this, so forgive any bugs. I just want to > convey the idea). > > module Enumerable > def select(&blk) > o = self.class.new > each{|*e| o << e if blk[*e]} > end > end > > class Hash > def <<(e) > self[e[0]] = e[1] > end > end > > The downside here is, it is less efficient and breaks backward > compatibility. It is a conceptional beauty but it really sucks for performance, there is *no* solution to our problem that is backward compatible, we explicitly ask for backward compatibility unless we go for a choosable Enum Mixin. Something like class Hash include TomsEnum end > > The other option would require an #each_assoc method (maybe assoc > isn't the best term, but anyhow...) > > module Enumerable > def select_assoc(&blk) > h = {} > each_assoc{|k,v| h[k]=v if blk[k,v]} > h > end > end > > The downside here of course, is twice the number of Enumerable > methods. And although I cannot imagine a case, how do we know that there are not Enumerables that take three or fourtytwo params ;). After all Enumerable is a Mixin and we have to be prepared that it be mixed in, right? Robert -- You see things; and you say Why? But I dream things that never were; and I say Why not? -- George Bernard Shaw