【问题标题】:Ruby concat! or <<! (how to modify state of object elegantly)红宝石连接!或 <<! (如何优雅地修改对象的状态)
【发布时间】:2012-12-21 11:48:31
【问题描述】:

有没有更优雅的方法来做到这一点:

widget.notes.where(:author_id => a).first.message= widget.notes.where(:author_id => a).first.message << "Potato"

例如,以下行不通:

widget.notes.where(:author_id => a).first.message << "Potato"
widget.notes.where(:author_id => a).first.message <<! "Potato"

分别不修改,或者返回错误(因为没有

<<!

操作员)

key:小部件是小部件的一个实例。小部件可以有注释。 Notes 有一个用于 :message 的 attr_accessible。 'a' 只是一个用户实例。

【问题讨论】:

  • (widget.notes.where(:author_id => a).first.message
  • 那是因为它返回一个字符串...... derp......也许我应该为它写一个proc,因为它可能不是内置的

标签: ruby-on-rails ruby operators


【解决方案1】:

这不是&lt;&lt; 没有就地修改字符串的问题——它确实就地修改了字符串。 &lt;&lt; 的名称中可能没有 !,但它仍然像一个 bang 方法。如果在示例代码中将 &lt;&lt; 替换为对 gsub! 的调用(名称中确实有 !),您可以轻松看到这一点:它不会有任何区别。

在您的情况下,您会返回未更改的字符串,因为 widget.notes.where(:author_id => a).first 可能每次都会返回一个新对象,该对象将具有自己的独立字符串。

此外,如果 message 对应于数据库列,而不是实例变量,我不确定在其上调用变异方法是否会起作用,因为它会绕过调用 ActiveRecord(或您正在使用的任何 ORM)设置器方法。在这里使用+= 可能是您最安全的选择。

这应该可以按您的意愿工作:

note = widget.notes.where(:author_id => a).first
note.message += "Potato"
note.save

【讨论】:

  • pjumble 刚刚删除了一条完美的评论! : widget.notes.where(:author_id => a).first.tap { |w| w.message += "土豆" }.save!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多