Ruby:为什么这种使用map的方法会引发错误?

Ruby:为什么这种使用map的方法会引发错误?,ruby,Ruby,我试着缩短 values.map{| value | value.gsub!(“\n”,”)} 与 values.map(&:gsub!(“\n”,”) 但它给了我一个: SyntaxError: ...csv_creator.rb:40: syntax error, unexpected '(', expecting ')' values.map(&:gsub!("\n", ' ')) 有人知道发生了什么吗?&:method表示法使用的是#to_proc方法,该方法能够将符

我试着缩短

values.map{| value | value.gsub!(“\n”,”)}

values.map(&:gsub!(“\n”,”)

但它给了我一个:

SyntaxError:
...csv_creator.rb:40: syntax error, unexpected '(', expecting ')'
     values.map(&:gsub!("\n", ' '))

有人知道发生了什么吗?

&:method
表示法使用的是
#to_proc
方法,该方法能够将符号转换为
proc
对象。如果需要为被调用的方法提供附加参数,则不能将其用作快捷方式

有关
#to_proc
的详细说明,请参见单独的答案:

备选方案 字符串#方法 只是为了说明可以做什么:您可以定义
String
方法而不带参数

class String
  def replace_newlines!(replace = ' ')
    gsub!("\n", replace)
  end

  def replace_newlines(replace = ' ')
    gsub("\n", replace)
  end
end

p new_values = values.map(&:replace_newlines)
#=> ["1 2", "a b"]

p values.each(&:replace_newlines!)
#=> ["1 2", "a b"]
遗憾的是,用
来处理

过程 另一种可能是定义一个新的
Proc
,而无需对
String
进行猴子补丁:

my_gsub = proc { |string| string.gsub("\n", ' ') }
p new_values = values.map(&my_gsub)
#=> ["1 2", "a b"]
每个/map/gsub/gsub! 请注意,
map
一起使用时没有多大意义方法。你应该:

  • 使用
    map
    gsub
  • 或者将
    每个
    gsub一起使用

&:foo
可能被错误地视为
&
foo
(像“foo”这样的术语强化了这一错误观点)。但是这里没有调用方法
foo
&:foo
实际上是
&
:foo
,后者是一个普通符号

调用方法时,
&object
(不带
)调用
对象。to_proc
(它应该返回a)并将返回的过程作为块参数传递给方法

object
通常是一个符号,它的实现在Ruby中看起来是这样的:(它实际上是用C编写的)

因此:

method(&:symbol)
实际上是这样的:

method { |object, *args| object.public_send(:symbol, *args) }
或者,如果
方法
不产生多个值(如
映射
),它只是:

method { |object| object.public_send(:symbol) }
显然,您不能通过符号传递额外的参数

但是<代码>对象
不必是符号。您可以使用另一个具有自定义
的类来执行
实现。让我们滥用
数组
进行演示:

class Array
  def to_proc
    method, *args = self
    proc { |obj| obj.public_send(method, *args) }
  end
end
这个黑客可以让你写:

["foo\nbar", "baz\nqux"].map(&[:gsub, "\n", '-'])
#=> ["foo-bar", "baz-qux"]

好主意。但是我认为我的老板不想让我在弦乐课上捣乱。很公平,我们可以说这只是为了展示可以做什么。关于
map
gsub的建议仍然有效。+1。不幸的是,你的答案没有回答我的主要问题(为什么它不起作用),所以我不能接受它作为最佳答案,即使它有更多的附加信息。当然,没问题@在我发布我的答案之前,萨缪尔有一个有效的答案。我只是想补充一些不适合评论的观点。我不得不说,非常好的观点。我也不知道也没想过
map
对我来说没有意义-我也不知道如何改进。吸取的教训!回答得好!非常感谢。
["foo\nbar", "baz\nqux"].map(&[:gsub, "\n", '-'])
#=> ["foo-bar", "baz-qux"]