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

我在’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:此处使用的代码只是为了演示问题。 我的实际代码看起来不像这样。

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

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

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

查看http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions,了解一些关于如何使用tap的更酷的例子。 不要用它来进行任务或修改,否则你会收到不稳定的结果。

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