我正在学习 Ruby 并查看了Array#map
这里的文档,它说语法如下
map {|element| ... } → new_array
map → new_enumerator
但是我们可以arr.map(&:to_s)
对数组的每个元素进行字符串化。据我所知,&:to_s
这只是语法糖:to_s.to_proc
(如此处所示),这意味着 map 接受一个Proc
对象作为参数。但它的函数签名却并非如此。
我对此有几个疑问。
有人可以解释这种行为并指出相关文档吗?
在这种情况下到底是什么
Proc
意思? 这不是to_s
底层类的方法吗? 对于我来说,传递一个没有关于将要调用的底层类Proc
的信息的对象意味着什么。to_s
任何帮助都将非常有帮助!
说“只是句法糖衣”并不完全准确,因为它掩盖了角色正在做的其他事情。
&:to_s
:to_s.to_proc
&
您可能知道 Ruby 中存在一种“文字块”语法,它有两种变体(文档):
对象
Proc
是具有特殊属性的对象,它可以代替文字块语法。因此,对于任何接受文字块的方法,您都可以向其传递一个
Proc
对象 - 但只能使用&
以下语法(docs):该
&
语法的意思是“使用这个 Proc 对象代替此方法的块参数,而不是作为常规的位置参数。”这就是“语法”发挥作用的地方。如果您使用
&
语法传递非Proc
对象,Ruby 会帮您尝试调用to_proc
该对象,将其转换为Proc
。您可以自己做同样的事情,但您不必这样做:&
在您的示例中,使用语法传递的对象:to_s
是一个Symbol
对象。由于它不是Proc
对象,因此 Ruby 会to_proc
对其进行调用。有一种方法Symbol#to_proc
( docs ) 可以将符号转换:to_s
为Proc
与 大致相同的符号{ |obj| obj.to_s }
。最终结果:
至于
Proc
文档对于块和s 的表示方式有些模糊。Proc
类文档 ( docs ) 的这一部分间接解决了这个问题:因此,如果您自己实现该
map
方法,参数签名可能如下所示:但是正如您所看到的,为了显示所需的块参数,Ruby 方法文档是按照您引用的方式编写的:
并且我认为文档中没有任何地方比上面已经链接的内容更好地解释这种确切的关系。