在浏览 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/