From: "David A. Black" Date: 2005-05-23T00:11:45+09:00 Subject: Re: join not in Enumerable Hi -- On Sun, 22 May 2005, Ara.T.Howard wrote: > On Sun, 22 May 2005, David A. Black wrote: > >> 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. [ ;-) ] 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 :-) >> In general, I think the design is a good one: Enumerable contains the most >> common methods (plus each_with_index :-) 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 ;-) 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 -- David A. Black dblack@wobblini.net