String对象上的'tap'方法不返回预期结果

时间:2009-08-26 01:53:30

标签: ruby-on-rails

我在'String'类型的对象上使用'tap'方法时遇到了一个有趣的问题。

"abc".tap { |o| o = "xyz" } # this line returns "abc" instead of "xyz"

'tap'方法适用于其他类型的对象。

[].tap { |o| o << "xyz" } # this line returns ["xyz"] as expected

我在Windows XP上使用Rails 2.3.2和Ruby 1.8.6。

我在这里缺少什么?

更新1:我解决了这个问题。这是我的使用错误。在第一个场景中,我将值重新分配给块参数而不是修改它。我能够重写代码并获得预期的结果。

"abc".tap { |o| o.replace "xyz" }

更新2:此处使用的代码仅用于演示此问题。我的实际代码看起来不像这样。

1 个答案:

答案 0 :(得分:8)

Object#tap在执行块后总是返回传入其中的原始对象,即使该块返回不同的内容。

这里的好处是您可以将tap放入链的中间并测试对象的值而无需修改原始值。

这意味着如果你将“abc”传递给tap,它将执行该块并返回“abc”。你对o的任务并不意味着任何由于范围界定的事情。同样,如果将空数组传递给tap,它将返回一个空数组。但是,在第二个示例中,您修改了原始值。修改原始内容的操作,例如&lt;&lt;或者gsub!或者同样会在返回之前修改对象,因此您将获得不同的值。

查看http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions以获取有关如何使用点按的更酷炫的示例。不要将它用于任务或修改,否则你会得到不可思议的结果。

更新:要进行编辑,为什么要解决您的问题?我不明白为什么当你可以在对象本身上调用replace时,你会调用tap来进行替换。为您提供什么好处?