On Mon, Jan 21, 2013 at 8:20 PM, David Richards <[email protected]> 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}
=> #<Proc:0x9284660@(irb):7>
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/
--
[email protected] |
https://groups.google.com/d/forum/ruby-talk-google?hl=en