On Jun 22, 2007, at 5:57 PM, Hell Feuer wrote:

> hmmm.. thnx. ur right. but even accepting that thats just how closures
> are, what about my second version?
>
>>> foo = lambda {p b}
>>> eval "b=1", foo
>>> foo.call
>
> 1) why does b get bound in the global scope???

There is nothing in your lambda to establish a binding for b.

> shouldn't it become local to to foo?

No.

> 2) and in any case, since b=1 is being evaluated in the context of  
> foo's
> binding, and foo is being called later, shouldn't this be  
> equivalent to
> defining b before foo is called (and therefore this shouldn't give an
> error)??

Only assignment brings b into existence.

> 3) if not, what does passing foo to eval actually do, since the
> behaviour seems to be the same whether or not i pass foo (i.e. the
> variable is bound in the global scope, and the closure cannot see it)

The binding of the Proc object is passed to eval.

Your second example suffers from the same problem as your first.

Also, consider the following tow examples:

<code>
bar = lambda { |b| b = b  }
b = 0
bar.call(42) # => 42
b # => 0
</code>

<code>
b = 0
bar = lambda { |b| b = b  }
bar.call(42) # => 42
b # => 42
</code>

In the first case, b is local to the block because no previous  
definition is visible, but in the second b is not local to the block  
because a previous definition is visible.

Finally, here is a quote from the pickaxe book that might clarify  
things for you:

<quote>
As of Ruby 1.8,local variables assigned within an eval are available  
after the eval
only if they were defined at the outer scope before the eval  
executed. In this way eval
has the same scoping rules as blocks.
</quote>

Regards, Morton