I tried to shorten
我试图缩短
values.map { |value| value.gsub!("\n", ' ') }
值。地图{ | |价值value.gsub !(“\ n”、“)}
with
与
values.map(&:gsub!("\n", ' '))
values.map(&:gsub !(“\ n”,' '))
but it gives me an:
但它给了我一个:
SyntaxError:
...csv_creator.rb:40: syntax error, unexpected '(', expecting ')'
values.map(&:gsub!("\n", ' '))
Anyone know what's going on?
有人知道发生了什么吗?
3 个解决方案
#1
3
&:foo
may erroneously be seen as &:
plus foo
(terms like "pretzel colon" reinforce this mistaken view). But no method foo
is being called here. &:foo
is actually &
plus :foo
, the latter being a plain symbol.
&:foo可能被错误地认为是&:+ foo(像“pretzel冒号”这样的术语强化了这个错误的观点)。但是这里没有调用foo方法。&:foo实际上是& +:foo,后者是一个普通的符号。
When calling a method, &object
(without :
) invokes object.to_proc
(which is supposed to return a Proc
) and passes the returned proc as a block argument to the method.
调用方法时,&object(没有:)调用对象。to_proc(应该返回一个Proc)并将返回的Proc作为块参数传递给方法。
object
often happens to be a symbol and Symbol#to_proc
's implementation would look somehow like this in Ruby: (it's actually written in C)
对象通常是一个符号和符号#to_proc的实现在Ruby:(它实际上是用C编写的)中看起来像这样
class Symbol
def to_proc
proc { |object, *args| object.public_send(self, *args) }
end
end
So this:
所以这个:
method(&:symbol)
effectively becomes this:
有效地成为这个:
method { |object, *args| object.public_send(:symbol, *args) }
or, if method
doesn't yield multiple values (like map
), it's simply:
或者,如果方法不产生多个值(如map),它只是:
method { |object| object.public_send(:symbol) }
Obviously, you can't pass additional arguments via a symbol.
显然,不能通过符号传递附加参数。
But ... object
doesn't have to be a symbol. You could use another class with a custom to_proc
implementation. Let's abuse Array
for demonstration purposes:
但是…对象不一定是符号。您可以使用另一个具有自定义to_proc实现的类。让我们滥用数组进行演示:
class Array
def to_proc
method, *args = self
proc { |obj| obj.public_send(method, *args) }
end
end
This hack would allow you to write:
你可以这样写:
["foo\nbar", "baz\nqux"].map(&[:gsub, "\n", '-'])
#=> ["foo-bar", "baz-qux"]
#2
3
&:method
notation is using #to_proc
method, which is capable of converting symbol to Proc
object. It can't be used as a shortcut if you need to provide additional arguments to called method.
方法符号使用#to_proc方法,它可以将符号转换为Proc对象。如果需要为所调用方法提供附加参数,则不能将其用作快捷方式。
Longer explanation about #to_proc
can be found in separate answer: What does to_proc method mean?
关于#to_proc的更详细的解释可以在单独的答案中找到:to_proc方法是什么意思?
#3
1
Alternatives
String#methods
Just to show what could be done : you could define String
methods without arguments.
只是为了说明可以做什么:您可以定义没有参数的字符串方法。
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"]
Sadly, refinements wouldn't work with to_proc
.
遗憾的是,改进不适用于to_proc。
Proc
Another possibility would be to define a new Proc
, without monkey-patching String
:
另一种可能是定义一个新的Proc,而不是monkey-patching字符串:
my_gsub = proc { |string| string.gsub("\n", ' ') }
p new_values = values.map(&my_gsub)
#=> ["1 2", "a b"]
each/map/gsub/gsub!
Note that map
doesn't make much sense when used with !
methods. You should either :
注意,map在使用时没有多大意义!方法。你应该:
- use
map
withgsub
- 使用地图gsub
- or use
each
withgsub!
- 或使用每一个与gsub!
#1
3
&:foo
may erroneously be seen as &:
plus foo
(terms like "pretzel colon" reinforce this mistaken view). But no method foo
is being called here. &:foo
is actually &
plus :foo
, the latter being a plain symbol.
&:foo可能被错误地认为是&:+ foo(像“pretzel冒号”这样的术语强化了这个错误的观点)。但是这里没有调用foo方法。&:foo实际上是& +:foo,后者是一个普通的符号。
When calling a method, &object
(without :
) invokes object.to_proc
(which is supposed to return a Proc
) and passes the returned proc as a block argument to the method.
调用方法时,&object(没有:)调用对象。to_proc(应该返回一个Proc)并将返回的Proc作为块参数传递给方法。
object
often happens to be a symbol and Symbol#to_proc
's implementation would look somehow like this in Ruby: (it's actually written in C)
对象通常是一个符号和符号#to_proc的实现在Ruby:(它实际上是用C编写的)中看起来像这样
class Symbol
def to_proc
proc { |object, *args| object.public_send(self, *args) }
end
end
So this:
所以这个:
method(&:symbol)
effectively becomes this:
有效地成为这个:
method { |object, *args| object.public_send(:symbol, *args) }
or, if method
doesn't yield multiple values (like map
), it's simply:
或者,如果方法不产生多个值(如map),它只是:
method { |object| object.public_send(:symbol) }
Obviously, you can't pass additional arguments via a symbol.
显然,不能通过符号传递附加参数。
But ... object
doesn't have to be a symbol. You could use another class with a custom to_proc
implementation. Let's abuse Array
for demonstration purposes:
但是…对象不一定是符号。您可以使用另一个具有自定义to_proc实现的类。让我们滥用数组进行演示:
class Array
def to_proc
method, *args = self
proc { |obj| obj.public_send(method, *args) }
end
end
This hack would allow you to write:
你可以这样写:
["foo\nbar", "baz\nqux"].map(&[:gsub, "\n", '-'])
#=> ["foo-bar", "baz-qux"]
#2
3
&:method
notation is using #to_proc
method, which is capable of converting symbol to Proc
object. It can't be used as a shortcut if you need to provide additional arguments to called method.
方法符号使用#to_proc方法,它可以将符号转换为Proc对象。如果需要为所调用方法提供附加参数,则不能将其用作快捷方式。
Longer explanation about #to_proc
can be found in separate answer: What does to_proc method mean?
关于#to_proc的更详细的解释可以在单独的答案中找到:to_proc方法是什么意思?
#3
1
Alternatives
String#methods
Just to show what could be done : you could define String
methods without arguments.
只是为了说明可以做什么:您可以定义没有参数的字符串方法。
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"]
Sadly, refinements wouldn't work with to_proc
.
遗憾的是,改进不适用于to_proc。
Proc
Another possibility would be to define a new Proc
, without monkey-patching String
:
另一种可能是定义一个新的Proc,而不是monkey-patching字符串:
my_gsub = proc { |string| string.gsub("\n", ' ') }
p new_values = values.map(&my_gsub)
#=> ["1 2", "a b"]
each/map/gsub/gsub!
Note that map
doesn't make much sense when used with !
methods. You should either :
注意,map在使用时没有多大意义!方法。你应该:
- use
map
withgsub
- 使用地图gsub
- or use
each
withgsub!
- 或使用每一个与gsub!