2011-03-06 33 views
0

我需要能够将变量的名称传递给表达式(在黄瓜中),并且希望能够将该字符串转换为变量的引用(即不是副本)。如何将字符串转换为对Ruby中变量的引用?

例如

Given /^I have set an initial value to @my_var$/ do 
    @my_var = 10 
end 

# and now I want to change the value of that variable in a different step 
Then /^I update "([^"]*)"$/ do |var_name_string| 
    # I know I can get the value of @my_var by doing: 
    eval "@my_var_copy = @#{var_name_string}" 

    # But then once I update @my_var_copy I have to finish by updating the original 
    eval "@#{var_name_string} = @my_var_copy" 

    # How do instead I create a reference to the @my_var object? 
end 

由于Ruby是这样一种反射语言,我相信我想要做的事情是可能的,但我还没有破解它。

回答

2
 
    class Reference 
    def initialize(var_name, vars) 
     @getter = eval "lambda { #{var_name} }", vars 
     @setter = eval "lambda { |v| #{var_name} = v }", vars 
    end 
    def value 
     @getter.call 
    end 
    def value=(new_value) 
     @setter.call(new_value) 
    end 
    end 

http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc得到这个。祝你好运!

+0

非常好 - 这是我所知道的,谢谢。它仍然不是100%,因为我需要使用ref_name.value,但它比我所得到的要好。 – 2011-03-08 17:15:46

+0

我上面提供的链接具有ref_name.value的示例用法。它应该可能有你所需要的。 – RubyFanatic 2011-03-08 18:37:46

0
+0

这是接近,但感觉它只是一个稍微干净的方式做一个评估。据我可以告诉它仍然不会返回对象本身的引用 – 2011-03-06 12:52:02

+0

在一个惊人的巧合,虽然这正是我需要做一些RSpec测试控制器:) – 2011-03-06 13:22:16

+0

不,你是对的。它不会返回引用,但会设置或获取实例变量的值。在我的理解你的黄瓜步骤,这就是你需要的。无论如何,至少它以某种方式帮助你:-) – 2011-03-06 14:02:19

1

解决方案可能是将东西包装到数组中。这可以很容易地通过参考传递。

irb(main):001:0> my_var = [10] 
=> [10] 
irb(main):002:0> my_var_copy = my_var 
=> [10] 
irb(main):003:0> my_var[0] = 55 
=> 55 
irb(main):004:0> my_var_copy 
=> [55] 

看到这里 - http://www.rubyfleebie.com/understanding-fixnums/

和(稍微偏离主题,但给了我一个解决方案最初的想法)在这里 - http://ruby.about.com/od/advancedruby/a/deepcopy.htm

+0

我实际上一直在使用一个散列日期和引用变量他们通过他们的基于字符串的密钥。这并不像我想要的那样接近,而是完成这项工作 – 2011-03-08 17:17:38