在Ruby中如何动态创建本地变量?

10

我正在尝试使用eval在Ruby中动态创建本地变量并改变本地变量数组。我是在IRB中进行的。

eval "t = 2"
local_variables # => [:_]
eval "t"
# => NameError: undefined local variable or method `t' for main:Object
local_variables << "t".to_sym # => [:_, :t]
t
# => NameError: undefined local variable or method `t' for main:Object

2
你为什么要这样做?目的是什么? - Sergio Tulentsev
@SergioTulentsev 我也问过完全相同的问题。很可能原始问题可以用更简单的方式解决。 - Patrick Oscity
3个回答

17

您需要使用相同的绑定对象来同步评估。否则,单个评估将具有自己的作用域。

b = binding
eval("t = 2", b)
eval("local_variables", b) #=> [:t, :b, :_]
eval("t", b) # => 2
b.eval('t') # => 2

2
@ppone:再说一遍,你想用那个实现什么目的? - Sergio Tulentsev
1
他的意思是为什么你要动态设置本地变量。你的问题可能可以通过其他方式解决,而不需要动态设置本地变量,最重要的是不要使用 eval - Patrick Oscity
3
我只是好奇为什么它没有被设置。你可能是对的,有一种更有效率的方法可以做到这一点。得到这个问题的答案有助于我更好地理解 Ruby。 - ppone
1
我仍然没有看到任何关于如何在现有上下文/绑定中动态创建局部变量的答案,因为binding总是创建一个新的上下文。 - Peter Alfvin
@PeterAlfvin 我以为你是。 - sawa
显示剩余9条评论

13

你需要使用正确的绑定(binding)。例如,在IRB中,可以这样做:

irb(main):001:0> eval "t=2", IRB.conf[:MAIN_CONTEXT].workspace.binding
=> 2
irb(main):002:0> local_variables
=> [:t, :_]
irb(main):003:0> eval "t"
=> 2
irb(main):004:0> t
=> 2

5
不需要经过伦理委员会审批吗?那 ruby myfile.rb 呢? - Sergio Tulentsev
@SergioTulentsev 我不确定,TOPLEVEL_BINDING和其他在ObjectSpace中的绑定实例似乎无法工作。 - Stefan

8
你可以像这样设置实例变量:

您可以这样设置实例变量:

instance_variable_set(:@a, 2)
@a
#=> 2

7
问题不是关于实例变量。 - Sergio Tulentsev
1
这是正确的,但也许这也可以解决OP所遇到的问题。正如我在原始问题的评论中已经说过的那样,我期望对于原始问题来说,有一个更简单的解决方案是可行的。 - Patrick Oscity
1
也作为另一种选择,请不要忘记使用define_method方法。 - Evgenia Karunus

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