Join not in Enumerable

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 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

And if you don't care about the "index" confusion in hash, you
could get these:

[], at, fetch, index, slice, values_at

Discover Yahoo!
Find restaurants, movies, travel and more fun for the weekend. Check it out!
http://discover.yahoo.com/weekend.html

···

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

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.

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 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. #flatten has no general
meaning for an enumerable, since not all of them are recursive
container objects. 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).

In general, I think the design is a good one: Enumerable contains the
most common methods (plus each_with_index :slight_smile: and specialized behavior
is left to the classes. Arrays provide a kind of normalized
representation through which some of those behaviors can be achieved
-- i.e., with #to_a you can hook into a lot of them. Finer
granularity would certainly be possible; there's been discussion, for
example, of separating Iterable (or something like that) out of
Enumerable.

David

···

On Sun, 22 May 2005, Eric Mahurin wrote:

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

--
David A. Black
dblack@wobblini.net

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.

hmm. i don't really see any possible implication with orderedness or index
confustion within enumerable methods - i guess it's because i think of
enumerable as, and only as, countable. because of that

   - no orderedness is implied : eg. in what order would you count a dozen
     eggs? doesn't much matter really, so long as you start at 0 and end at
     11. [ :wink: ]

   - which brings me to the second point. the notion of index is, and always
     is, with enumerable methods, the notion of my index in the the current
     count. again, with the eggs example, if i'm counting a dozen eggs then,
     at any point, i can tell you which egg i'm on : the 3rd, the 8th, etc.
     this is obviously my index into the count.

In general, I think the design is a good one: Enumerable contains the most
common methods (plus each_with_index :slight_smile: and specialized behavior is left to
the classes. Arrays provide a kind of normalized representation through
which some of those behaviors can be achieved -- i.e., with #to_a you can
hook into a lot of them. Finer granularity would certainly be possible;
there's been discussion, for example, of separating Iterable (or something
like that) out of Enumerable.

so i guess we are on the same page here except i'd call Iterable Countable and
then the each_with_index method fits right back in :wink: i can understand
someone seeing it an not entirely orthogonal, why not simply track your own
'index'?, yet the notion seems no natural when wants to do something like

   def sample collection
     ret = []
     collection.each_with_index{|x,i| (i >= 42 ? break ; (ret << x))}
     ret
   end

kind regards.

-a

···

On Sun, 22 May 2005, David A. Black wrote:
--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================

Hi --

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.

hmm. i don't really see any possible implication with orderedness or index
confustion within enumerable methods - i guess it's because i think of
enumerable as, and only as, countable. because of that

- no orderedness is implied : eg. in what order would you count a dozen
   eggs? doesn't much matter really, so long as you start at 0 and end at
   11. [ :wink: ]

It may not imply orderness, but it imposes an order. I think part of
the problem surrounding this has always been that hashes having
numerical indices, aside from imposing an order that means nothing,
collides head-on with the idea that a hash key is to the hash what an
array index is to the array.

In other words, one can say:

    Hashes have keys, values, and a thing called the "index" which is
    a 0-originating count for the key/value pairs.

or one can say:

    Where arrays have numerical indices, hashes have keys that don't
    have to be numbers.

but it doesn't make sense to say both.

Moreover, this also makes no sense:

   h = {1,2,3,4,5,6,7,8}
   h.each_with_index {|pair,i|
     puts "Found #{pair.join("=>")} at index 2" if i == 2
   }
   puts "h.index(2) is #{h.index(2)}"

There is a direct conflict of terminology here: "index" means two
completely different things in the case of a hash, depending which
method you're calling.

You could argue (and I think people have) that the "index" in
"each_with_index" is the index of an array resulting from an implicit
#to_a operation. And, sure enough, these two things are equivalent:

   h.each_with_index
   h.to_a.each_with_index

But to me that's just another indication that something is askew.

- which brings me to the second point. the notion of index is, and always
   is, with enumerable methods, the notion of my index in the the current
   count. again, with the eggs example, if i'm counting a dozen eggs then,
   at any point, i can tell you which egg i'm on : the 3rd, the 8th, etc.
   this is obviously my index into the count.

I've been asking for 4.5 years for someone to show me a case where
it's useful to have Hash#each_with_index, and I've never been shown
one :slight_smile:

In general, I think the design is a good one: Enumerable contains the most
common methods (plus each_with_index :slight_smile: and specialized behavior is left to
the classes. Arrays provide a kind of normalized representation through
which some of those behaviors can be achieved -- i.e., with #to_a you can
hook into a lot of them. Finer granularity would certainly be possible;
there's been discussion, for example, of separating Iterable (or something
like that) out of Enumerable.

so i guess we are on the same page here except i'd call Iterable Countable and
then the each_with_index method fits right back in :wink: i can understand
someone seeing it an not entirely orthogonal, why not simply track your own
'index'?, yet the notion seems no natural when wants to do something like

def sample collection
   ret = []
   collection.each_with_index{|x,i| (i >= 42 ? break ; (ret << x))}
   ret
end

I can't think of an unordered collection where that would be likely to
be useful. It looks like something you'd use on an array or a
filehandle, but not on a hash.

David

···

On Sun, 22 May 2005, Ara.T.Howard wrote:

On Sun, 22 May 2005, David A. Black wrote:

--
David A. Black
dblack@wobblini.net