我正在尝试理解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>
为什么没有定义a
?
如果我在规避之前声明a
,则将值42分配给a
。
在我看来,某些块范围适用于eval上下文中的局部变量可用,但声明的任何变量仅在块范围内声明。
如何在不创建新范围的情况下评估代码?
答案 0 :(得分:3)
为什么没有定义
a
?
a
在eval'd代码的绑定中定义,但不在其外部。这就是局部变量的工作原理。它们是它们所定义的范围的本地。这就是为什么它们被称为“本地”变量。毕竟。
如果我在规避之前声明
a
,则将值42分配给a
。
是的,eval
的范围嵌套,就像块范围一样。
如何在不创建新范围的情况下评估代码?
你做不到。在Ruby 1.8和之前的版本中,eval
确实会将变量泄漏到周围的范围内,但是泄漏在1.9及更高版本中已得到修复。
答案 1 :(得分:1)
这是因为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 > 1.times{|a| b=1}
=> 1
2.2.1 :002 > b
NameError: undefined local variable or method `b' for main:Object
from (irb):2
from /home/hbranciforte/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
但是......
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 >
实例变量有效,因为它是&#34; self&#34;
2.2.1 :001 > eval "@b = 42"
=> 42
2.2.1 :002 > @b
=> 42
2.2.1 :003 >
看看如何将上下文发送到方法。来自http://ruby-doc.org/core-2.2.0/Binding.html
def get_binding(param)
return binding
end
b = get_binding("hello")
b.eval("param") #=> "hello"
我不知道我是否清楚,但我想说的是,真正重要的真实事情是ruby将分配/释放内存及其访问权限的上下文(或范围)。