From: Alan Forrester Date: 2013-01-22T05:22:24+09:00 Subject: Re: Enumerator usage On 21 Jan 2013, at 19:20, David Richards wrote: > I don't understand the following: > > 3.times { |i| puts(i) } # ok > 3.times.class # Enumerator > n = 3.times > n.class # Enumerator > n { |i| puts(i) } # error!? > > To a new Ruby student this error seems 'conceptually wrong'. > > Playing around a bit I've discovered that this works: > > n.each { |i| puts(i) } > > As does: > > 3.times.each { |i| puts(i) } > > Does this inconsistency result from a parser-level layer of 'syntactic > sugar'? I'm also getting a sense that a 'block' is a parser-level > construct, > and a 'Proc' is an execution-level object. > > So, a related question: given an Enumerator and a 1-ary Proc (lambda): > > n = 3.times > f = lambda { |i| puts(i) } > > What expression allows us to 'map' or 'apply' the Proc to each > enumerated value? > > There just seems to be something really 'wrong' about how Ruby treats > functions: > > def f2(i) > puts(i) > end > > f2.class # error!? > > Functions are not first-class objects? I actually have no idea what f2 > is. Clearly its not a symbol bound to an object. It's 'something else'. > > Intuitively I would have expected the follow two constructs to produce > operatively identical objects: > > def f2(i) > puts(i) > end > > f2 = lambda { |i| puts(i) } > > I'm really puzzled by this. Coming from years of programming in Scheme > I'm quite used to dealing with syntax-layer transformations. But there > is evidently something else going on with Ruby that violates a lot of my > intuitions and expectations. I'm hoping that once I understand it better > it will start to look 'elegant' and 'beautiful', but right now it looks > kinda 'scary' and 'repugnant'. > > Help please! In Ruby objects are not first first class. The commonly given reason for this is that non-first-class blocks are faster because you don't have to create objects to use them: http://mudge.name/2011/01/26/passing-blocks-in-ruby-without-block.html Alan