From: "David A. Black" Date: 2008-08-06T23:57:20+09:00 Subject: [ruby-core:18150] Re: Enumerators that know about a block Hi -- On Wed, 6 Aug 2008, Shugo Maeda wrote: > Hi, > > 2008/8/6 David A. Black : >> 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!