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"]