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

时间:2011-09-19 20:42:48

标签: ruby-on-rails ruby ruby-on-rails-3 rspec rspec2

我正在使用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_< 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

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

1 个答案:

答案 0 :(得分:1)

您应该使用.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
  • 的返回值指定值