From: Alexander Presber Date: 2007-06-22T00:20:09+09:00 Subject: Re: Behaviour of Enumerables reject vs. select mixed into Hash > 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 I agree, that seems to solve the problem very elegantly. The implementation of << would be the second precondition for the possibility to mix Enumerable in (the first being implementing each). It allows for all "filter" methods to return a filtered version of the original object, class and all. This solution is general and provides for arbitrary future classes to mix in Enumeration. > The downside here is, it is less efficient and breaks backward > compatibility. > > 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. Or n times, for n classes that mix in Enumerable. That sounds bad, imho. Sincerely yours, Alex