如何“以编程方式”“迭代地”将每个类对象属性设置为一个值?

我正在使用Ruby on Rails 3.0.9和RSpec 2.我试图以下面的方式重构一些spec文件(为了测试更少的代码类似的类对象属性值):

[ :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_' (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_' 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 

如何改进上面的代码以实现我的目标 (我引用user.send(:"#{attr}") = 'a_value'部分以便“以编程方式”设置 – 即设置不同的属性每次迭代的值 – 每个用户属性值为'a_value'

您应该使用.send并在方法名称后附加一个=来调用setter,并将值作为第二个参数传递send

 [ :attribute_a, :attribute_b, :attribute_c ].each do |attr| before do user.send("#{attr}=", 'a_value') end 

你实际上是这样做的:

 user.send('attribute_a=', 'a_value'); 

你的语法( user.send(:"#{attr}") = 'a_value' )是错误的/奇怪的,原因如下:

  • 没有理由将:attr转换为字符串,然后立即返回符号
  • 您不能为.send的返回值.send