为什么有时我可以不使用 splat 运算符而逃脱

Why was I able to get away with not using a splat operator sometimes

我在 Rails 项目的 Ruby 中有一些 ruby 代码。

我正在格式化一些数据,因此我正在调用 attributes.extract! 以从我的模型中获取我需要的字段。

我最近注意到,有时数据不会按预期提取。我意识到我需要一个 splat 运算符。但这很奇怪,因为我注意到有时在我的 Rails 项目中调用该方法时,它有时会在不使用 splat 运算符的情况下提取数据。但是,当我 运行 来自 Rails 控制台的代码时,除非我添加 splat 运算符,否则它永远不会提取数据。

这是有问题的代码

  # in a service file, let's call it service.rb
  def self.format_user_home_address_data(user)
    # This doesn't work in the console but sometimes works when run in my Rails project
    home_address_data = user.attributes.extract!(User::HOME_ADDRESS_FIELDS)

    home_address_data[:address_type] = "home"
    home_address_data
  end

  # at the end this method will sometimes return { address_type: "home" } or 
  # sometimes it'll actually return the extracted attributes as expected

HOME_ADDRESS_FIELDS 只是一个包含值 ["address_line_1", "city", "state", "zip"]

的数组

不管怎样,我知道要正确地 运行 我需要这样做

    home_address_data = user.attributes.extract!(*User::HOME_ADDRESS_FIELDS)

但是有人知道为什么我这么长时间不添加 splat 运算符就能逃脱吗? Rails 上是否有一些 Ruby 魔法只是偶尔发生?怎么回事?

好吧,让我们检查一下。 attributes.extract! 最后没有任何魔法。这是 Rails 源代码中此方法的实际实现:

def extract!(*keys)
  keys.each_with_object(self.class.new) { |key, result| 
    result[key] = delete(key) if has_key?(key) 
  }
end

Link:click。如您所见,它创建了新的哈希值,一个一个地遍历 keys 并将值从 self 移动到这个新数组。所以,如果你给这个方法一个数组参数,那么块中的 key 也将是一个数组。所以,不会被发现。所以,它不可能适用于数组参数。唯一的一种可能性是传递了其他内容而不是 User::HOME_ADDRESS_FIELDS.