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