Hi --

On Wed, 6 Aug 2008, Shugo Maeda wrote:

> Hi,
>
> 2008/8/6 David A. Black <dblack / rubypal.com>:
>> I'd rather have an enumerator that already knows both the method it
>> represents and the block it's supposed to use. I guess I got used to
>> it when we had:
>>
>>  e = array.enum_for(:map, &block)
>>
>> and I never understood why that was removed. I think it's someone
>> else's "least surprise" :-)
>
> First of all,
>
>  e = array.enum_for(:map)
>  p e.each(&block)
>
> is equivalent to:
>
>  p e.map(&block)
>
> Then,
>
>  e = array.enum_for(:map, &block1)
>  p e.each(&block2)
>
> is equivalent to:
>
>  p e.map(&block2)
>  # block1 is ignored for the same reason that Kernel#print ignores blocks.
>
> I would be surpised if it's equivalent to:
>
>  p e.map(&block1).each(&block2)
>
> or
>
>  p e.map(&block1).map(&block2)
>
> But you want this behaviour, don't you?

I guess I was surprised when this stopped working:

   array = [1,2,3,4,5]
   e = array.enum_for(:map, &lambda {|x| x * 10 })
   e.select {|x| x > 30 }     # [40, 50]

I don't have any strong reason for it except that it seems to me to
make enumerators much more powerful. (But maybe at a cost.)

> Speaking about implementation, Enumerable#map is impletented as follows:
>
> module Enumerable
>  # actually implemented in C
>  def map
>    result = []
>    each do |i|
>      result << yield(i)
>    end
>    return result
>  end
> end
>
> How do you convert it into Enumerator as you think automatically?  I can't
> think of any implementation other than the following example:
>
> module Enumerable
>  def my_enum_for(method, &block)
>    return send(method, &block).enum_for(:each)
>  end
> end
>
> But it's not efficient, and I think it's necessary for an efficent
> implementation
> to modify Enumerable#map itself.

I'm not sure how it was implemented originally. If it's just going to
create the intermediate object and then an enum_for on that object, it
doesn't make sense for performance.


David

-- 
Rails training from David A. Black and Ruby Power and Light:
  *  Advancing With Rails    August 18-21    Edison, NJ
  * Co-taught by D.A. Black and Erik Kastner
See http://www.rubypal.com for details and updates!