2017-03-03 70 views
-1

我有一類這樣的:爲什麼在課堂上CONSTANT值被改變了?

class Example 
    DEFAULT_VALUE = { 
     'first_key': ['a', 'b'], 
     'second_key': 'c' 
    } 

    def append_new_value(value) 
    default_value_copy = DEFAULT_VALUE 
    default_value_copy[:first_key] << value 
    puts "default_value_copy: #{default_value_copy}" 
    puts "DEFAULT_VALUE: #{DEFAULT_VALUE}" 
    end 
end 

example = Example.new 
example.append_new_value('d') 
example.append_new_value('e') 

的結果是:

default_value_copy: {:first_key=>["a", "b", "d"], :second_key=>"c"} 
DEFAULT_VALUE: {:first_key=>["a", "b", "d"], :second_key=>"c"} 
default_value_copy: {:first_key=>["a", "b", "d", "e"], :second_key=>"c"} 
DEFAULT_VALUE: {:first_key=>["a", "b", "d", "e"], :second_key=>"c"} 

正如我前面的理解,DEFAULT_VALUE的價值不應該被調用append_new_value方法後改變。

你們能幫我解釋一下這種情況嗎?

+0

常數不變。常量引用的對象。 Ruby不是一種純粹的函數式語言,對象可以改變。 –

回答

0

首先,Ruby沒有類似於其他語言期望的常量概念。 Ruby常量可以更改值。如果你想指定一個對象不應該在Ruby中發生變異,你必須使用Object#freeze方法。

然後,通過引用或值的方式傳遞方法參數。你可以說Ruby是傳統意義上的傳值。然而在Ruby中,所有變量都是對象的引用,所以如果你將一個對象傳遞給一個方法,它確實會發生變異。

如果您正在尋找不變性的快速勝出,請查看Object#dup

+0

'dup'只創建一個淺拷貝,即'DEFAULT_VALUE [:first_key]'和'DEFAULT_VALUE.dup [:first_key]'仍然指向同一個數組。 – Stefan

+0

@Stefan你是對的。在這個例子中不適用,我只是提到它作爲參考。 – gkats

相關問題