[英]What is the purpose of options.dup in Ruby on Rails?
瀏覽Rails代碼庫,我發現了很多對options.dup的引用。
def to_xml(options = {})
require 'builder' unless defined?(Builder)
options = options.dup
....
end
顯然,options.dup正在復制選項哈希,但為什么你希望在這種情況下這樣做呢?
dup
克隆一個對象。 將對象傳遞給方法時,任何更改該對象內部狀態的內容都將反映在調用范圍中。 例如,嘗試以下代碼:
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
,然后對克隆所做的任何更改都不會反映在調用范圍中:
def replace_two(options)
options = options.dup
options[:two] = "hi there"
end
options = { one: "foo", two: "bar" }
replace_two(options)
puts options[:two]
將打印bar
。 這是遵循最小驚訝原則的常見模式。 在Ruby中,修改其參數的方法通常以a命名!
后綴以提醒用戶他們是破壞性/修改操作。 該方法的非dup
版本應該被稱為replace_two!
表明這種副作用。
dup
創建對象的淺表副本。 這是紅寶石的核心東西。 因為像Hash和Array這樣的ruby對象是通過引用傳遞的,所以當你更改一個函數內部的對象時,這將改變原始對象。 如果這不是所希望的行為 - 你創建一個副本......所以代碼確實如此。
請參閱ruby-doc
UPDATE
還有一件事。 由於object是通過引用傳遞的,因此options = options.dup
將為新創建的副本分配options
變量引用。 在to_xml
丟失了對原始對象的to_xml
。 但它仍然可能在調用to_xml
代碼中引用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.