问题
I need to be able to pass the name of a variable into an expression (in cucumber) and would like to be able to convert that string into a reference (i.e. not a copy) of the variable.
e.g.
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
Since Ruby is such a reflective language I'm sure what I'm trying to do is possible but I haven't yet cracked it.
回答1:
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
Got this from http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc. Good luck!
回答2:
A solution might be to wrap things into an array. Which can easily be passed around by reference.
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]
See here - http://www.rubyfleebie.com/understanding-fixnums/
And (slightly off topic, but gave me the initial idea for a solution) here - http://ruby.about.com/od/advancedruby/a/deepcopy.htm
回答3:
Could obj.instance_variable_get and obj.instance_variable_set help you?
来源:https://stackoverflow.com/questions/5210411/how-do-i-convert-a-string-into-a-reference-to-a-variable-in-ruby