Hi --

On Mon, 20 Sep 2004, Florian Gross wrote:

> Let me propose yet another alternative. (More general than my last one.) 
> Let .each yield(item, *more) and make all methods provided by Enumerable 
> pass on *more.
> 
> This would allow Hash#each to do this:
> 
>    class Hash
>      def each
>        loop over key => value pairs do
>          yield(value, key)
>        end
>      end
> 
>      include Enumerable
>    end
> 
>    hash = {1 => 2, 3 => 4}
>    hash.each { |value,| puts value }
>    hash.map { |value, key| [key, value] } # from hash to assoc array
>    hash.inject(0) { |state, value, key| state + [value, key].hash }
> 
> and Array to do this:
> 
>    class Array
>      def each
>        0.upto(size - 1) do |index|
>          yield(self[index], index)
>        end
>      end
> 
>      include Enumerable
>    end
> 
>    array = ["hello", "nice", "world"]
>    array.find_all { |item, index| index > 0 }
>    array.each { |item,| p item }
> 
> I still dislike the trailing comma that is needed if you don't want to 
> use the extra information. This could be fixed by doing an arity check 
> on blocks and not yielding the extra information when the block only 
> wants a single argument.

The trailing comma, and the sense that it's impossible to just iterate
purely over the elements, is bad -- but other than that, I think I
like the idea.  

> Also note that this means we won't have to deal with all the 
> #map_with_index and so on trouble any more, Hash wouldn't need to 
> virtually overwrite any method provided by Enumerable and that we can 
> even easily make Enumerables that yield other information. (Is anybody 
> able to think about a good use for that feature?)

You could send a "last item" flag (Hal, are you reading? :-)  Also you
could have 1-originating indices.  


David

-- 
David A. Black
dblack / wobblini.net