Ruby Procs - 最终会出现语法错误

时间:2016-05-01 17:12:22

标签: ruby proc

试图理解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使用+方法,为什么最后一次给我这个语法错误?我做错了什么?

2 个答案:

答案 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,因此收到语法错误。