From: Robert Klemme Date: 2013-01-22T05:36:57+09:00 Subject: Re: Enumerator usage On Mon, Jan 21, 2013 at 8:20 PM, 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!? Yes, because there is no method "n". The block makes it parse as a method call. > 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. In a way: Proc is the class of the block instance: irb(main):006:0> def f(&b) b end => nil irb(main):007:0> x = f {|a| puts a} => # irb(main):008:0> x.class => Proc > 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? Invoking method #each as you've shown above. More correctly, invoking *any* method will do. Some methods just ignore the block. > There just seems to be something really 'wrong' about how Ruby treats > functions: > > def f2(i) > puts(i) > end > > f2.class # error!? Ruby is not a functional language so methods are not first class objects. > 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'. Keyword "def" introduces a method definition. The method is bound to a class (what class depends on context) under the identifier given. > 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) } They won't. > 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'. It will be easier for you if you stop expecting Ruby to be a functional programming language - it isn't. As simple as that. Ruby is a dynamically but strictly typed object oriented programming language. Even though it has some support for functional style programming and also real closures. Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/