Morton Goldberg
6/23/2007 12:23:00 AM
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