Create local variable in Binding after it's creation

Hi,

Is it possible to create a new local variable in a binding after it's creation?

Specifically, what I'd like to do:

  l = lambda { puts a } # 'a' not defined at this point.
  eval('a = 7', l.binding) # Hope to create a in l's binding
  l.call # Hope to get '7'

- but that produces:

  NameError: undefined local variable or method `a' for main:Object
          from (irb):1
          from (irb):3:in `call'
          from (irb):3

Apparently, 'a' gets created in the scope from where 'eval' was called and not in 'l'''s binding.

Any suggestions would be most welcome.

best regards
Christian Surlykke

···

from :0

Is it possible to create a new local variable in a binding after it's creation?

You can create it, but you won't be able to use it directly.

Specifically, what I'd like to do:

  l = lambda { puts a } # 'a' not defined at this point.
  eval('a = 7', l.binding) # Hope to create a in l's binding
  l.call # Hope to get '7'

l = lambda{ eval 'a' }
eval('a = 7', l.binding)
l.call # => 7
eval('a') # => 7

If you try to use 'a' before the parser sees 'a = ...', it will be considered
a method call, and you'll get a NameError even if you give it a value
afterwards/in eval.

BTW. this is changing in 1.9.

···

On Sun, Nov 12, 2006 at 11:06:44PM +0900, Christian Surlykke wrote:

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby

Søndag 12 november 2006 15:18 skrev Mauricio Fernandez:

If you try to use 'a' before the parser sees 'a = ...', it will be considered
a method call, and you'll get a NameError even if you give it a value
afterwards/in eval.

Ah, I see. Thanks.

BTW. this is changing in 1.9.

In what way? My example seems to work the same way with ruby-1.9...

best regards

Christian Surlykke

maybe one should suggest a different approach to OP.
Can you use instant variables, or will that be impacting elsewhere

p = Proc.new { puts @a }
@a= Guess what?
p.call

And yes Mauricio can you give a pointer to the new behavior please, thx.

Cheers
Robert

(1) Well I do not, but that remains between us :wink:

···

On 11/12/06, Mauricio Fernandez <mfp@acm.org> wrote:

On Sun, Nov 12, 2006 at 11:06:44PM +0900, Christian Surlykke wrote:
> Is it possible to create a new local variable in a binding after it's
creation?

You can create it, but you won't be able to use it directly.

> Specifically, what I'd like to do:
>
> l = lambda { puts a } # 'a' not defined at this point.
> eval('a = 7', l.binding) # Hope to create a in l's binding
> l.call # Hope to get '7'

l = lambda{ eval 'a' }
eval('a = 7', l.binding)
l.call # => 7
eval('a') # => 7

If you try to use 'a' before the parser sees 'a = ...', it will be
considered
a method call, and you'll get a NameError even if you give it a value
afterwards/in eval.

BTW. this is changing in 1.9.

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby

I do not want to argue with Mauricio, I know when I am outclassed(1), but

--
The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore all progress
depends on the unreasonable man.

- George Bernard Shaw

Both
eval("a = 7")
eval("a")
and
eval("a = 7", binding)
eval("a")
will raise a NameError in the future, so you'll have to do
binding = binding # heh
eval("a = 7", binding)
eval("a", binding)

[ruby-core:09388]

This can be seen as a step towards less inclusive closures and lambda lifting.

···

On Sun, Nov 12, 2006 at 11:27:07PM +0900, Christian Surlykke wrote:

Søndag 12 november 2006 15:18 skrev Mauricio Fernandez:

> If you try to use 'a' before the parser sees 'a = ...', it will be considered
> a method call, and you'll get a NameError even if you give it a value
> afterwards/in eval.

Ah, I see. Thanks.

>
> BTW. this is changing in 1.9.

In what way? My example seems to work the same way with ruby-1.9...

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby

>> Specifically, what I'd like to do:
>> l = lambda { puts a } # 'a' not defined at this point.
>> eval('a = 7', l.binding) # Hope to create a in l's binding
>> l.call # Hope to get '7'
>l = lambda{ eval 'a' }
>eval('a = 7', l.binding)
>l.call # => 7
>eval('a') # => 7
>
>If you try to use 'a' before the parser sees 'a = ...', it will be
>considered a method call, and you'll get a NameError even if you give it a
>value afterwards/in eval.
>
>BTW. this is changing in 1.9.

(Just to be clear, "this" == semantics of eval("local_var")).

And yes Mauricio can you give a pointer to the new behavior please, thx.

[ruby-core:09388]

I'll be glad to see that happen; it's something I've been wanting for some
time. I became concerned about closures being "too wide" by the end of
2003/early 2004 and was close to writing a RCR.
(http://thekode.net/misc/survey.txt --- note: I'm not collecting responses
anymore :slight_smile:
[ruby-core:09388] can be interpreted as a step in that direction.

PS: your email made me think of the zero derivation of eigenclass and
"verbing" it in sentences like
  "I want to eigenclass myself" or
  "eigenclassing oneself demands constant effort"
which could be the first use ever with the obvious newly-coined? acception :slight_smile:

···

On Mon, Nov 13, 2006 at 12:22:26AM +0900, Robert Dober wrote:

On 11/12/06, Mauricio Fernandez <mfp@acm.org> wrote:
>On Sun, Nov 12, 2006 at 11:06:44PM +0900, Christian Surlykke wrote:

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby