我试着缩短
values.map { |值| value.gsub!("\n", ' ') }
与
values.map(&:gsub!("\n", ' '))
但它给了我一个:
SyntaxError:
...csv_creator.rb:40: syntax error, unexpected '(', expecting ')'
values.map(&:gsub!("\n", ' '))
有人知道这是怎么回事吗?
最佳答案
&:foo
可能会被错误地视为 &:
加上 foo
(像“pretzel colon”这样的术语强化了这种错误观点)。但是这里没有方法 foo
被调用。 &:foo
实际上是 &
加上 :foo
,后者是一个普通符号。
当调用一个方法时,&object
(没有:
)调用object.to_proc
(应该返回一个Proc
)并且将返回的过程作为 block 参数传递给方法。
object
通常恰好是一个符号,Symbol#to_proc
的实现在 Ruby 中看起来像这样:(它实际上是用 C 编写的)
class Symbol
def to_proc
proc { |object, *args| object.public_send(self, *args) }
end
end
所以这样:
method(&:symbol)
实际上变成了这样:
method { |object, *args| object.public_send(:symbol, *args) }
或者,如果 method
不产生多个值(如 map
),它只是:
method { |object| object.public_send(:symbol) }
显然,您不能通过符号传递额外的参数。
但是 ... object
不一定是符号。您可以使用另一个具有自定义 to_proc
实现的类。让我们滥用 Array
进行演示:
class Array
def to_proc
method, *args = self
proc { |obj| obj.public_send(method, *args) }
end
end
这个 hack 可以让你写:
["foo\nbar", "baz\nqux"].map(&[:gsub, "\n", '-'])
#=> ["foo-bar", "baz-qux"]
关于Ruby:为什么这种使用 map 的方式会抛出错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41853364/