为什么to_proc不在Ruby优化中工作?

Pat*_*ois 5 ruby proc refinements

它似乎to_proc不适用于优化中定义的方法:

module ArrayExtensions
  refine Array do
    def sum
      reduce(0, :+)
    end
  end
end

using ArrayExtensions

puts [[1, 2, 3]].map { |array| array.sum } # => 6
puts [[1, 2, 3]].map(&:sum) # => array.rb:13:in `map': undefined method `sum' for [1, 2, 3]:Array (NoMethodError)
puts [1, 2, 3].method(:sum).to_proc.call # => array.rb:14:in `method': undefined method `sum' for class `Array' (NameError)
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?有解决方法吗?

Ale*_*kin 3

注意以下答案对于传统红宝石来说是正确的。在 Ruby 2.5+ 中可以按预期map(&:sum)工作。


改进的范围仅限于当前环境。由于细化的目的不是全局的,与猴子补丁相反,任何从外部调用细化方法的尝试都会被阻止。在下面的代码中:

puts [[1, 2, 3]].map { |array| array.sum } # => 6
Run Code Online (Sandbox Code Playgroud)

范围很好,我们处于定义此细化的同一范围内。但在这儿:

puts [[1, 2, 3]].map(&:sum)
Run Code Online (Sandbox Code Playgroud)

范围被转移到Symbol类的上下文(!)。如文档中所述:

当控制权转移到范围之外时,细化将被停用。

这里的类比是私有方法。虽然,虽然它与文档中所述完全相同,但我不确定这种行为是否是有意为之。我认为,口译员应该注意此类情况。但这个问题最好解决 Matz :)

PS好问题!