问题
I am using Ruby on Rails 3.0.9 and RSpec 2. I am trying to refactoring some spec file in the following way (in order to test with less code similar class object attribute values):
[
:attribute_a,
:attribute_b,
:attribute_c
].each do |attr|
before do
# HERE I would like to set the "current" 'attr' related to the
# class object instance 'attribute_< letter >' (read below for
# more information) each time the iterator is called (note: all
# following attributes are NOT attr_accesible - for that reason
# I use the 'user.attribute_< letter >' in the 'before do'
# statement)
#
# # Iteration 1
# user.attribute_a = 'a_value'
# # No changes to 'user.attribute_b'
# # No changes to 'user.attribute_c'
#
# # Iteration 2
# # No changes to 'user.attribute_a'
# user.attribute_b = 'a_value'
# # No changes to 'user.attribute_c'
#
# # Iteration 3
# # No changes to 'user.attribute_a'
# # No changes to 'user.attribute_b'
# user.attribute_c = 'a_value'
# Maybe I should make something like the following but that, as well
# as the 'send' method must be used, doesn't work (the below code-line
# is just an example of what I would like to do).
#
# user.send(:"#{attr}") = 'a_value'
end
...
end
How can I improve the above code so to accomplish what I aim (I refer to the user.send(:"#{attr}") = 'a_value'
part in order to set "programmatically" - that is, set a different attribute value for each iteration made - each user attribute value to 'a_value'
)?
回答1:
You should use .send
and append an =
to the method name to invoke the setter, passing the value as the second argument to send
:
[
:attribute_a,
:attribute_b,
:attribute_c
].each do |attr|
before do
user.send("#{attr}=", 'a_value')
end
You're effectively doing this:
user.send('attribute_a=', 'a_value');
Your syntax (user.send(:"#{attr}") = 'a_value'
) is wrong/weird for a couple reasons:
- There's no reason to convert
:attr
to a string and them immediately back to a symbol - You can't assign a value to the return value of
.send
来源:https://stackoverflow.com/questions/7477062/how-to-set-programmatically-iteratively-each-class-object-attribute-to-a-val