为什么Ruby只允许在调用to_proc时按符号引用方法?

时间:2016-01-18 20:24:50

标签: ruby symbols proc

这有效:

strings = ["1", "2", "3"]
nums = strings.map(&:to_i)

我们看到&应用于Symbol对象的( to_proc 方法)变为块。 但是,这不起作用:

strings = ["1", "2", "3"]
nums = strings.map(&to_i)
nums = strings.map("to_i".to_sym.to_proc) #...neither does this

为什么不起作用?是否有任何替代方法来编写上面的代码?我很困惑,因为有两种方法可以访问类的方法:

"1".method(:to_i).call #works as well as
"1".method("to_i").call 

因此可以通过符号或字符串访问方法的名称。

2 个答案:

答案 0 :(得分:4)

给出以下有效的Ruby示例:

"to_i".to_sym.to_proc.call("1")

在符号上调用#to_proc会创建一个接收一个参数的proc:应该接收对符号命名的方法的调用的对象。像这样:

->(object) {
  object.send(:to_i)
}

&做的是将#to_proc返回的块作为正确的调用块传递给被调用的方法。与Enumerable#map一起使用时,最终结果是传递 将为集合和接收上的每个元素调用块 当前迭代元素作为参数传递给块。

因此["1", "2"].map(&:to_i)语法是类似的快捷方式 这样:

block = ->(el) {
  el.send(:to_i)
}

["1", "2"].map &block

关于您的示例:

当您尝试在示例中调用&to_i时,Ruby将尝试调用 名为to_i的变量或方法。因为它不存在于 范围(它是String中每个Array的方法,而不是"全局"范围内的方法),它会产生错误。

关于另一个例子:"to_i".to_sym.to_proc将改变 :to_i进入一个proc,当用一个参数调用时,将尝试 调用以符号(:to_i)命名的方法对目标 参数。这意味着您可以使用&来转换proc 进入"调用块":

["1", "2"].map(&"to_i".to_sym.to_proc)

答案 1 :(得分:0)

nums = strings.map(&to_i)

不起作用,因为主要环境中未定义to_i

nums = strings.map("to_i".to_sym.to_proc)

不起作用,因为Proc实例不是块。块甚至不是对象。

你可以写:

nums = strings.map(&"to_i".to_sym)