在浏览 Rails 代码库的过程中,我发现了许多对 options.dup 的引用。

def to_xml(options = {})
  require 'builder' unless defined?(Builder)
  options = options.dup
  ....
end

显然 options.dup 正在复制 options 哈希,但是您为什么要在这种情况下这样做呢?

最佳答案

dup 克隆一个对象。当您将对象传递给方法时,任何更改该对象内部状态的内容都将反射(reflect)在调用范围中。例如,试试这个代码:

def replace_two(options)
  options[:two] = "hi there"
end

options = { one: "foo", two: "bar" }
replace_two(options)
puts options[:two]

这将打印 hi there ,因为 replace_two() 修改了哈希内容。

如果要避免更改传入的 options ,可以对其调用 .dup ,然后对克隆所做的任何更改都不会反射(reflect)在调用范围中:
def replace_two(options)
  options = options.dup
  options[:two] = "hi there"
end

options = { one: "foo", two: "bar" }
replace_two(options)
puts options[:two]

将打印 bar 。这是遵循 Principle of Least Astonishment 的常见模式。在 Ruby 中,修改参数的方法通常以 ! 后缀命名,以提醒用户它们是破坏性/修改操作。该方法的非 dup 版本应该被称为 replace_two! 以指示这种副作用。

关于ruby-on-rails - Ruby on Rails 中 options.dup 的目的是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15681531/

10-13 02:18