新手问题 弱弱问个问题: 如果将一个字符串作为变量?

scuwolf · December 24, 2015 · Last by qinfanpeng replied at December 24, 2015 · 2742 hits

如何通过a_val这个变量的值 ("aaa") 来定义一个 aaa的变量,我知道 eval 可以做到,但是 eval 定义的只是 eval 内部可以访问的局部变量。还有其他的方法可以定义一个 eval 外部可以访问的局部变量么?

1.9.3-p547 :010 > a_var='aaa'
 => "aaa" 
1.9.3-p547 :011 > eval "#{a_var}='bbb'; aaa"
 => "bbb" 
1.9.3-p547 :012 > aaa
NameError: undefined local variable or method `aaa' for main:Object
    from (irb):12
    from /home/coremail/.rvm/rubies/ruby-1.9.3-p547/bin/irb:12:in `<main>'
1.9.3-p547 :013 > 

帮你谷歌了一下。

不可以。

可以定义成方法

局部变量不能这么用的,而且像 php 那么实现会拖累性能

你可以用哈希表

h = {}
h['a_var'] = 'aaa'
h['a_var'] = 'bbb'
h['a_var'] # 'bbb'

@scuwolf,建议你采用@ywjno 的建议定义成方法;如果实在要按照你的方法整的话,可以用闭包把变量带出来:

2.2.0-preview1 :008 > a_var='aaa'
 => "aaa"
2.2.0-preview1 :009 > v = eval "#{a_var}='bbb'; ->{aaa}"
 => #<Proc:0x007f99ee8a03b0@(eval):1 (lambda)>
2.2.0-preview1 :010 > v.call
 => "bbb"

或者用 instance_variable_set 定义成实例变量

我默默的告诉楼主一个可以实现的方法

1.把你的 ruby 版本下降到 1.8

2.在 irb 中使用,在 rb 文件里还是不行的。

看这里

I read from somewhere that now Ruby can't dynamically create local variable. Is it true or just a bug?

The local variables are created in compile time, so that local variables that are defined in eval() cannot be accessed outside of eval. In 1.8, irb and tryruby does line by line compilation so that local variables are spilled from eval(), but in 1.9, it's strictly prohibited even under line-by-line compilation.

matz.

原因在这里

In Ruby 1.8, all evals under a given scope (like, at the same scoped level in a method) used the same shared local variable scope. That scope grew as needed to accommodate new variables.

In Ruby 1.9, every eval gets its own scope. This provides better isolation between evals, which has both positive and negative side effects. On the positive side, the code inside an eval can use a faster representation of local variables that doesn't depend on being able to grow. On the negative side, you can't do things like this anymore:

在 1.8 之后,eval 创建的局部变量是在自己独立的 scope 下面的。

@adamshen 除了说你给力外,还能说啥呢~~~1.8 版本都被拉出来了!

多谢楼上几位,开阔思路了

#4 楼 @qinfanpeng

要暴露 scope 其实也可以用 binding 的:

a_var = 'aaa'
b = eval("#{a_var}='bbb';binding")
eval(a_var, b)
You need to Sign in before reply, if you don't have an account, please Sign up first.