From: "David A. Black" Date: 2004-09-21T19:57:34+09:00 Subject: Re: Array#index block and rdetect Hi -- On Tue, 21 Sep 2004, Robert Klemme wrote: > > "Yukihiro Matsumoto" schrieb im Newsbeitrag > news:1095736691.496867.14110.nullmailer@x31.priv.netlab.jp... > > Hi, > > > > In message "Re: Array#index block and rdetect" > > on Tue, 21 Sep 2004 10:56:51 +0900, "David A. Black" > writes: > > > > |Here's one possibility. I don't think this would be bad for > > |compatibility, because Array would have its *_index methods, and I > > |don't think #each_with_index is used much (ever?) for anything except > > |arrays and maybe array subclasses. > > | > > | Enumerable: > > | > > | each_with_counter # "dumb" counters, for every enumerable, > > | each_counter # strictly based on incrementing through > > | # #each > > > > No need for each_counter, for there's no way for general enumerables > > to map from counters to values. If it's possible, it's rather > > suitable to be called as index. By the way, do you agree with the > > word 'counter'? It's kinda burden for me, non English speaker, to > > tell the word nuance. > > I'd prefer to keep #each_with_index because that has least impact on > existing code. I'm really not worried about that, since Array would still have it (see below). Also, all of this is in the spirit of assuming there will be backward-incompatible changes in 2.0. > > | Array: > > | > > | each_with_index # either very similar to, or identical to, > > | each_index # the *_counter methods (because that > > | # happens to be how arrays work). > > > > No objection here. > > > > | Hash and other enumerable classes: > > | > > | In addition to the *_counter methods, each enumerable class > > | can have its own, "smart" methods (just as Array does with > > | its *_index methods). They can have "index" in the name, > > | if appropriate -- but they do not have to. (There are no > > | Enumerable#*_index methods.) > > > > Do you have any opinion toward Hash#each_with_index? > > Here's my suggestion: > > class Array > alias :each_with_key :each_with_index > def keys; (0...size); end > def values; self; end > def to_assoc; inject([]) {|a,e| a<<[a.size, e]} end > end > > class Hash > def each_with_key > each {|k,v| yield v,k} > end > > alias :to_assoc :to_a > end > > Note that I deliberately maintained each_with_index as well as the order > of key and value (first value, then key). It comes down in part to terminology. I don't like calling array indexes "keys", even though I completely understand how they relate to hash keys. It just seems artificial; no one does it. I also don't like the word "index" for the "dumb counter" in Enumerable. A lot of the reason we're discussing changes is that the word "index" is used in different ways, giving the impression that there is a connection between arguably unconnected things. > Note also, that #to_a is a problem when we want to make Hash and Array > more interchangable: Hash#to_a returns keys and values while Array#to_a > just returns values. That's why I put in #to_assoc. Also #sort doesn't > fit the pattern... Maybe we should rather go with a thin wrapper around > Array (or a sub class) that implements these methods in a Hash compatible > way. I'm still not happy with the idea of wrappers and such. I think it should be possible to have arrays and hashes just be what they are. They have some points of overlap, but they really don't have to be constrained to be too similar to each other. David -- David A. Black dblack@wobblini.net