Ruby eval 在 irb 和文件中的行为不同

发布于 2024-07-16 04:00:30 字数 1006 浏览 4 评论 0原文

这段代码在 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)

任何人都可以解释为什么吗?

This code works in 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>

however when I try to execute the same code as a ruby script I get the following error:

../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)

can anyone explain why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海螺姑娘 2024-07-23 04:00:30

这是因为运行 eval 时尚未定义 machine 变量。 更简洁的示例:

在 IRB 中工作,但不作为脚本

eval 'x = 3'
puts x # throws an exception when run as a script
=> 3

在 IRB 中工作并作为脚本

x = 1
eval 'x = 3'
puts x
=> 3

引用 Matz

局部变量应该在编译时确定,因此局部变量
在评估字符串中首先定义的变量只能从
其他评估过的字符串。 此外,它们将更加短暂
Ruby2中,这样这些变量就不会被外部访问。

不同之处在于,在 IRB 中,一切都会被评估,因此它们都在同一范围内。 也就是说,您实际上是在 IRB 中执行此操作:

eval 'x = 3'
eval 'puts x'

它既可以在 IRB 中工作,也可以作为脚本工作。

It's because the machine variable was not already defined when eval was run. A more concise example:

Works in IRB but not as a script

eval 'x = 3'
puts x # throws an exception when run as a script
=> 3

Works in IRB and as a script

x = 1
eval 'x = 3'
puts x
=> 3

To quote Matz:

local variables should be determined at compile time, thus local
variables defined first in the eval'ed string, can only be accessed from
other eval'ed strings. In addition, they will be more ephemeral in
Ruby2, so that these variables will not be accessed from outside.

The difference is that in IRB everything is being eval'd, so it's all in the same scope. That is, you're essentially doing this in IRB:

eval 'x = 3'
eval 'puts x'

Which works both in IRB and as a script.

拒绝两难 2024-07-23 04:00:30

因为您是在 IRB 中而不是在 Ruby 脚本中定义名为 machine 的方法或变量。

Because you're defining a method or variable named machine in IRB but not in your Ruby script.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文