Join not in Enumerable

Hi --

>> I have to say, though, that I think #each_with_index
should
>> be removed
>> from Enumerable and pushed down to the classes that mix it
in
>> (similarly to #each_index). But I suppose as long as they
>> are called
>> "enumerable" they are in some sense associated with a
>> numerical index.
>
> Unfortunately for Hash, this can cause confusion to what an
> "index" is. If it weren't for an already existing
Hash#index
> (which gets a key), I would suggest it be brought over from
> Array to Enumerable.

I see it the other way. "Index" means different things to
different
enumerables. I don't like the idea of having Enumerable
define index
as consecutive integers slapped onto the elements. I'd
rather defer
that to the classes -- as, indeed, it is, with the strange
exception
of each_with_index.

I was agreeing with you - each_with_index confuses what an
"index" is for Hash (or Hash#index does depending on how you
look at it).

> I do tend to think that many of the Array methods should be
> brought over to Enumerable. You could bring over just
about
> any one that is non-modifying and operates sequentially
forward
> on the array, but you may also restrict the ones related to
an
> "index":
>
> *, +, <=>, ==, assoc, compact, concat, empty?, eql?, first,
> flatten, hash, join, last, length, nitems, pack, rassoc,
size,
> to_s, uniq

Some of these would fare better than others.

agreed. I just listed all of them that were read-only and
operate sequentially forward in across the array. I think all
of these could be easily implemented in enumerable, but not all
make necessarily make sense.

#flatten has no general
meaning for an enumerable, since not all of them are
recursive container objects.

Array#flatten only descends into Array elements, and an
Enumerable#flatten might only descend into Enumerable (or
Array) elements.

I don't think you can #pack an arbitrary
enumerable either. #size also doesn't work for enumerables
in
general, partly because some of them have no particular size
and
partly because even for those that do, taking the size might
cause
side-effects (e.g., an I/O-based enumerable).

Using any enumerable method with IO has the same issue. You'll
need to seek back between calls to any of the enumerable
methods on an IO.

Of course their is an easy (but not quite as efficient) way to
do any of the array methods on an enumerable: just call to_a
first (i.e. enum.to_a.join(" ") does a join for any
enumerable).

Yahoo! Mail
Stay connected, organized, and protected. Take the tour:
http://tour.mail.yahoo.com/mailtour.html

···

--- "David A. Black" <dblack@wobblini.net> wrote:

On Sun, 22 May 2005, Eric Mahurin wrote:
> --- "David A. Black" <dblack@wobblini.net> wrote:

Hi --

#flatten has no general
meaning for an enumerable, since not all of them are
recursive container objects.

Array#flatten only descends into Array elements, and an
Enumerable#flatten might only descend into Enumerable (or
Array) elements.

It just seems like a bad fit for, say, iterating through lines of a
file. I don't think being enumerable implies being flattenable,
because it doesn't imply being nested (whereas being an array implies
that you might be nested). Therefore I wouldn't put flatten in
Enumerable.

I don't think you can #pack an arbitrary
enumerable either. #size also doesn't work for enumerables
in
general, partly because some of them have no particular size
and
partly because even for those that do, taking the size might
cause
side-effects (e.g., an I/O-based enumerable).

Using any enumerable method with IO has the same issue. You'll
need to seek back between calls to any of the enumerable
methods on an IO.

Size has the other problem too: being enumerable does not mean being
measurable. For example:

   class C
     include Enumerable
     def each
       loop { yield rand(100) }
     end
   end

It's meaningless to talk about the size of a C object -- but it's a
perfectly legitimate enumerable.

Of course their is an easy (but not quite as efficient) way to
do any of the array methods on an enumerable: just call to_a
first (i.e. enum.to_a.join(" ") does a join for any
enumerable).

I'm not sure that it's less efficient than some of these. For
example, see the exchange earlier in the thread about to_a vs. inject
in join; the efficient inject seemed to benchmark around the same as
to_a (though presumably this would vary from one case to another). Of
course, I'm not sure one of my C objects, above, would respond to
nicely to to_a.... :slight_smile:

David

···

On Mon, 23 May 2005, Eric Mahurin wrote:

--
David A. Black
dblack@wobblini.net