Ruby 为什么Symbol#to_proc会有这种行为?
我发现这个示例代码在Ruby中实现了自定义符号#to_proc:Ruby 为什么Symbol#to_proc会有这种行为?,ruby,Ruby,我发现这个示例代码在Ruby中实现了自定义符号#to_proc: class Symbol def to_proc puts "In the new Symbol#to_proc!" Proc.new { |obj| obj.send(self) } end end 它包括额外的“puts…”字符串,以确保它不是内置方法。当我执行代码时 p %w{ david black }.map(&:capitalize) 结果是: In the new Symbol#t
class Symbol
def to_proc
puts "In the new Symbol#to_proc!"
Proc.new { |obj| obj.send(self) }
end
end
它包括额外的“puts…”字符串,以确保它不是内置方法。当我执行代码时
p %w{ david black }.map(&:capitalize)
结果是:
In the new Symbol#to_proc!
["David", "Black"]
但为什么不是这样呢
In the new Symbol#to_proc!
["David"]
In the new Symbol#to_proc!
["Black"]
我的逻辑是这样的:映射产生一个接一个的元素来块。块获取第一个元素并执行.to_proc,而不是第二个。但是为什么puts只执行一次?调用
to_proc
方法一次,返回一个proc对象,然后重复使用,因此您看到了正确的行为
如果您将puts移动到内部,您将看到您所期望的:
class Symbol
def to_proc
Proc.new { |obj|
puts "In the new Symbol#to_proc!"
obj.send(self)
}
end
end
在Ruby中,map使用块。
&
操作符调用它后面的对象上的到_proc
,并将调用到_proc
返回的值作为一个块
进行映射。有了这些信息,让我们再看看您的示例。在您的示例中,&:capitalize
将导致调用以调用:capitalize
上的\u proc
方法。由于,:capitalize
是一个符号,它将调用来处理符号类上的
,由您重新定义
:capitalize.to_proc
将返回:
In the new Symbol#to_proc!
=> #<Proc:0x007fa08183df28@(irb):4>
在新符号中#to_proc!
=> #
&
操作符将使用返回的Proc对象,并将该Proc对象作为块传递给map。在重新定义的to_proc
方法定义中,put
刚刚开始执行,由于put
打印到控制台(假设您在控制台中运行),您将看到它被打印。它从来没有传递给地图,所以你永远不会看到它打印两次
然而,如果你想要你期望的行为,使用第一个答案。希望能有帮助。@bjhaid:这不是重复的答案。“没问题。@bjhaid:嗯,是的,我不同意你的观点。谢谢你的解释,但我不明白为什么Proc对象只创建一次。为什么不为每个映射块调用创建新的Proc对象?我确信Ruby能够正确地执行代码,但我找不到一个很好的解释来解释这种情况。为什么您希望每个循环都有一个全新的过程?这将是非常浪费的,因为
map
和类似函数的整个思想是将完全相同的函数应用于许多对象。如果要对每个元素应用不同的函数,则应使用each
,其中包含一个自定义代码位。这给了你最大的灵活性。这是一个完美的答案,现在我明白发生了什么。谢谢