Ruby:为什么这种使用 map 的方式会抛出错误?

标签 ruby

我试着缩短

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/

相关文章:

ruby-on-rails - PayPal 的 Website Payments Pro 是否需要账单地址?

mysql - 哪个 ruby​​ mysql 库支持准备语句和 last id 检索

javascript - 为什么我的字符串只有在我手动输入时才有效?

ruby - 如何在 Ruby pg gem 中使用 PG::Connection 类的 send_query?

ruby - $addToSet 用于哈希?

ruby-on-rails - "::"前面的 "::Rails::Engine"是什么意思

ruby-on-rails - 无法理解 ActionCable

mysql - 如果有非法字符,如何将密文保存到数据库?

ruby-on-rails - 具有可能不同类型 mongoid 的字段

mysql - 轨道 3 : Measure database performance (MongoDB and MySQL)