这有效:
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
因此可以通过符号或字符串访问方法的名称。
答案 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)