试图理解Ruby上的Procs,为此我尝试了一些练习。
首先我输入这一行
[1, 4, 5, 3].map(&:anything)
结果我收到了一个错误:
NoMethodError:未定义的方法
anything' for 1:Fixnum
。
然后我试试这个:
[1, 4, 5, 3].map(&:to_s)
返回了一个数字转换为字符串的新数组:
=> [" 1"," 4"," 5"," 3"]`。
通过这两个例子,我可以得出结论,当我调用类似于[1, 4, 5, 3].map(&:anything)
的内容时,会为数组中的每个元素调用anything
方法。并且因为Fixnum没有实现anything
方法,所以第一个示例以错误结束,第二个示例以第二个示例结束。
然后我认为,如果Fixnum有+
方法,那么我可以调用[1, 4, 5, 3].map(&:+2)
。但这会以语法错误结束:
语法错误,意外的tINTEGER,期待')' [1,4,5,3] .map(&:+ 2)
如果Fixum使用+
方法,为什么最后一次给我这个语法错误?我做错了什么?
答案 0 :(得分:2)
&
是调用to_proc
方法的快捷方式。
因为您有一个符号(:anything
),所以在符号上调用to_proc
方法。这将返回一个proc,它将在作为参数传递的对象上调用具有相应名称(anything
)的方法。
如果您使用map
之类的枚举器执行此操作,那么您实际上会在集合中的每个对象上调用该方法。
现在,此快捷方式不允许您将参数传递给方法。 (+
只是用于在一个数字上调用方法的语法糖,该方法将另一个方法作为参数)
但你可以将currying用于这样一个用例:
add = -> (a, b) { a + b }
add_two = add.curry.call(2)
p [1,2,3,4].map(&add_two) # => [3, 4, 5, 6]
答案 1 :(得分:1)
&:method_name
是一种可以用来代替{|x| x.anything}
的快捷方式 - 而且只是那个。它可以被任何接收块的方法使用。
# So this line...
[1,2,3].map(&:anything)
# ... is equivalent to this line
[1,2,3].map {|x| x.anything }
# Same can go here:
[job1, job2, job2].each(&:process)
请注意,您只能将它用于不接收参数的方法。由于您尝试发送参数2
,因此收到语法错误。