Ruby每个都有对象合成糖的解释

时间:2016-07-13 12:36:10

标签: ruby

为什么这些不平等?

['a'].each_with_object('b'){|x,memo| memo << x}
=> "ba"

['a'].each_with_object('b', &:<<)
=> "b"

我认为第二个只是第一个的语法糖化版本。

2 个答案:

答案 0 :(得分:2)

Symbol#to_proc返回Proc arity -1的实例:

:<<.to_proc.arity
#⇒ -1

也就是说,它会默默地接受任意数量的参数,然后基本上调用args.first.method(self).to_proc并将上面的结果作为codeblock参数传递给调用者。这就是['a'].reduce('b', :<<)按预期工作的原因:reduce的第一个块参数为memo

'b'.method(:<<, 'a')

返回"ba"字符串。

您的代码的工作方式相同:

arr = ['a']
arr.each_with_object('b', &:<<)
arr
#⇒ ['ab']

您只是期望String#<<方法的接收器错误。在这种情况下,接收器是一个数组元素,因为它作为第一个参数传递给块。看:

arr = ['a', 'b']
arr.each_with_object('z', &:<<)
arr
#⇒ ['az', 'bz']

memo本身保持不变,并在调用each_with_object后返回。您甚至可能拥有它frozen,代码仍然有效。

尽管如此,使用Symbol#to_proceach_with_object无法实现您使用语法糖请求的功能。

答案 1 :(得分:0)

返回的对象是传递给each_with_object的第一个参数。在第一个示例中,第一个对象"b"附加了&#34; a&#34;,并返回该对象。在第二个示例中,接收器"a"的元素附加了第一个参数"b",但第一个参数没有任何反应。