我有一个嵌套数组:
a = [[1, "Aldous Huxley"],
[3, "Sinclair Lewis"],
[2, "Ernest Hemingway"],
[4,"Anthony Burgess"]]
a.collect { |author| author.drop(1) }
输出
[["Aldous Huxley"], ["Sinclair Lewis"], ["Ernest Hemingway"], ["Anthony Burgess"]]
,而
a.collect(&:drop(1))
给我一个sintax错误。
SyntaxError: (irb):18: syntax error, unexpected '(', expecting ')'
a.collect(&:drop(1))
^
是否可以在&amp ;: syntax?
中定义原始块表达式答案 0 :(得分:6)
不,这是不可能的。
&
语法是语法糖,字面意思如下:
Proc
个实例,并在其上调用to_proc
; (&:foo)
有效,因为Symbol.to_proc
存在。
(&:foo(arg))
无法解析,因为:
之后需要有效的符号字符,而左括号会引发语法错误。
答案 1 :(得分:6)
冒号是Ruby中Symbol的一部分,&
是通过调用对象上的to_proc
并将其用作块来实现该语法的神奇工具。因此,虽然您不能使用:drop(1)
之类的符号,但您可以在不使用符号的情况下完成此操作:
1)从方法中返回一个proc并将其传递给:
def drop(count)
proc { |instance| instance.drop(count) }
end
a.collect(&drop(1))
2)传入响应to_proc
的对象:
class Drop
def initialize(how_many = 1)
@to_drop = how_many
end
def to_proc
proc { |instance| instance.drop(@to_drop) }
end
end
drop = Drop.new(1)
a.collect(&drop) # or, more succinctly
a.collect(&Drop.new(1))
在这种简单的情况下,定义返回procs或响应to_proc
的对象的方法可能有点过分,只是将块传递给collect
更好,但可能会有一些用例不是。
更新:考虑到这一点,Symbol
类没有call
方法,但这并不意味着它不能:
module SymbolCall
def call(*args)
proc { |instance| instance.public_send(self, *args) }
end
end
class Symbol
include SymbolCall
end
a.collect(&:drop.(1)) # or
a.collect(&:drop.call(1))
请确保您不要忘记它实际上是一种方法调用:drop.(1)
而不是 :drop(1)
。