使用eval进行变量赋值

3
使用eval分配实例变量是有效的,而另一种方法不起作用。试图理解这里发生了什么。任何帮助都将不胜感激。
>> var = "a value"
=> "a value"

>> @v
=> nil

>> eval "@v = var"
=> "a value"

>> @v
=> "a value"

>> eval "var_new = var"
=> "a value"

>> var_new
NameError: undefined local variable or method `var_new' for main:Object
        from (irb):7
        from C:/Ruby193/bin/irb:12:in `<main>'

eval 创建一个新的作用域,而 var_new 是该作用域的 局部变量 - Sergio Tulentsev
@v 是包含对象的实例变量(在 irb 中,它是 Object 的一个实例 - 至少在 1.8.7 中是这样),因此可以从 eval 访问,并且由于作用域限制在对象中,所以它会保留下来。 - Neil Slater
3个回答

3

eval有自己的作用域。你可以访问在eval之前定义的变量,但无法访问在eval内部定义的变量。

就作用域而言,你的示例类似于:

var = "a value"

1.times do # create new scope
  new_var = var
end

new_var
# NameError: undefined local variable or method `new_var' for main:Object

3

eval会创建自己的作用域:

>> i = 1; local_variables.count
=> 2
>> eval "j = 1; local_variables.count"
=> 3
>> local_variables.count
=> 2

这是否意味着实例变量不在 eval 的本地作用域中? - Bala
实例变量仍然存在,并且仍然在对象的上下文中。通过将 ij 替换为 @i@j,并将 local_variables 替换为 instance_variables,查看上面的测试。最终您将按预期增加实例变量的数量。 - Denis de Bernardy

2

以下是进行一种内省的方法:

var = "a value"
eval "var_new = var,defined?(var_new)" #=> ["a value", "local-variable"]
defined?(var_new) #=>nil
defined?(var) #=>"local-variable"
defined?(temp) #=>nil

您可以看到,var_new 只在 eval 内部被识别。在 eval 之外,tempvar_new 都是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接