Ruby 在不创建块范围的情况下运行eval

Ruby 在不创建块范围的情况下运行eval,ruby,Ruby,我试图理解Ruby中的eval和绑定上下文 在irb中考虑以下内容 irb(main):001:0> eval "a = 42" => 42 irb(main):002:0> a NameError: undefined local variable or method `a' for main:Object from (irb):2 from /Users/niels/.rbenv/versions/2.1.3/bin/irb:11:in `<main>' irb

我试图理解Ruby中的eval和绑定上下文

在irb中考虑以下内容

irb(main):001:0> eval "a = 42"
=> 42
irb(main):002:0> a
NameError: undefined local variable or method `a' for main:Object
from (irb):2
from /Users/niels/.rbenv/versions/2.1.3/bin/irb:11:in `<main>'
irb(main):003:0> 
irb(主):001:0>评估“a=42”
=> 42
irb(主要):002:0>a
NameError:未定义的局部变量或main:Object的方法“a”
来自(irb):2
from/Users/niels/.rbenv/versions/2.1.3/bin/irb:11:in`'
irb(主要):003:0>
为什么
a
没有定义

如果我在求值之前声明
a
,则值42被分配给
a

在我看来,某些类型的块作用域适用于局部变量在eval上下文中可用的情况,但是任何声明的变量都只在块作用域中声明


如何在不创建新范围的情况下评估代码?

这是因为a与irb不在同一上下文中

看看这个代码

2.2.1 :001 > eval "a = 42"
 => 42 
2.2.1 :002 > a
NameError: undefined local variable or method `a' for main:Object
    from (irb):2
    from /home/hbranciforte/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
就像

2.2.1 :001 > b=nil
 => nil 
2.2.1 :002 > 1.times{|a| b=1}
 => 1 
2.2.1 :003 > b
 => 1 
2.2.1 :004 > 
实例变量之所以有效,是因为它是“self”的一部分

看看如何将上下文发送到方法。从

我不知道我是否清楚,但我想说的是,真正重要的是ruby将分配/取消分配内存和访问的上下文(或范围)

为什么
a
没有定义

a
在评估代码的绑定内定义,但不在评估代码之外。这就是局部变量的工作原理。它们位于定义它们的范围的局部。这就是为什么它们被称为“局部”变量的原因

如果我在求值之前声明
a
,则值42被分配给
a

是的,
eval
的作用域嵌套,就像块作用域一样

如何在不创建新范围的情况下评估代码


你不能。在Ruby 1.8及之前的版本中,
eval确实会将变量泄漏到周围的范围中,但该泄漏在1.9及以后的版本中得到了修复。

您很清楚,我们的结论是相同的,但是Ruby的eval似乎是不完整的。我希望
a=3
eval“a=3”
产生完全相同的行为。也许提供一个关键字参数,如<代码>评估“a=3”,新范围:true
生成当前行为。
2.2.1 :001 > a=nil
 => nil 
2.2.1 :002 > eval "a = 42"
 => 42 
2.2.1 :003 > a
 => 42 
2.2.1 :001 > b=nil
 => nil 
2.2.1 :002 > 1.times{|a| b=1}
 => 1 
2.2.1 :003 > b
 => 1 
2.2.1 :004 > 
2.2.1 :001 > eval "@b = 42"
 => 42 
2.2.1 :002 > @b
 => 42 
2.2.1 :003 > 
def get_binding(param)
  return binding
end
b = get_binding("hello")
b.eval("param")   #=> "hello"