我想迭代一个字符串数组,并将它们分配给一个新的User类实例,我希望我会得到一个User对象数组:
class User
def name=(name)
@name = name
self
end
end
original_array = ["aaa", "bbb", "bbb"]
result = original_array.collect { |str| User.new.name = str }
但结果是一个字符串数组!
puts result.inspect # => ["aaa", "bbb", "bbb"]
puts result === original_array # => true
我不知道我哪里出错了?
答案 0 :(得分:5)
这里错误的是User.new.name = str
会返回str
,因此会收集str
的值。
为什么会返回str
?因为,与任何其他Ruby方法相反,每个Ruby setter方法都返回传递的值,而不管方法中的返回值。有关此行为的更多信息,您可以查看this other SO answer。
在IRB-ready概念证明之下:
def name=(name)
@name = 'another value'
end
returned_value = (self.name = 'a value')
returned_value #=> 'a value'
@name #=> 'another value'
您可以通过以下方式完成所需的工作:
此语法对任何Ruby对象都有效,因为它使用Object#tap
:
User.new.tap { |v| v.name = str }
如果User
是ActiveRecord
模型,我猜你可以使用其中一种略短的语法:
User.new name: str
User.new { |v| v.name = str }