此代码适用于irb:
irb(main):037:0> eval <<-EOS
irb(main):038:0" #{attribute} = "host"
irb(main):039:0" puts machine
irb(main):040:0" EOS
host
=> nil
irb(main):041:0> puts machine
host
=> nil
irb(main):042:0> puts attribute
machine
=> nil
irb(main):043:0>
然而,当我尝试执行与ruby脚本相同的代码时,我收到以下错误:
../autosys/convert_jil_to_zapp.rb:40: undefined local variable or method `machine' for main:Object (NameError)
from ../autosys/convert_jil_to_zapp.rb:29:in `each_line'
from ../autosys/convert_jil_to_zapp.rb:29
from ../autosys/convert_jil_to_zapp.rb:27:in `each'
from ../autosys/convert_jil_to_zapp.rb:27
pi929c1n10 /ms/user/h/hirscst/ruby/autosys 77$ gvim try.rb
pi929c1n10 /ms/user/h/hirscst/ruby/autosys 78$ chmod +x try.rb
pi929c1n10 /ms/user/h/hirscst/ruby/autosys 79$ ./try.rb
host
./try.rb:8: undefined local variable or method `machine' for main:Object (NameError)
任何人都可以解释原因吗?
答案 0 :(得分:12)
这是因为machine
运行eval
时尚未定义eval 'x = 3'
puts x # throws an exception when run as a script
=> 3
变量。一个更简洁的例子:
x = 1
eval 'x = 3'
puts x
=> 3
eval 'x = 3'
eval 'puts x'
局部变量应该在编译时确定,因此是本地的 首先在eval'ed字符串中定义的变量,只能从中访问 其他评估的字符串。此外,他们将更加短暂 Ruby2,这样就不会从外部访问这些变量。
区别在于,在IRB 中,所有都被评估,因此它们都在相同的范围内。也就是说,你基本上是在IRB中这样做的:
{{1}}
在IRB和脚本中都有效。
答案 1 :(得分:0)
因为您在IRB中定义了一个名为machine
的方法或变量,但在Ruby脚本中却没有。