T
Trans
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.
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.
T.