2017-03-03 3 views
-1

Ich habe eine Klasse wie folgt:Warum der CONSTANT-Wert in der Klasse geändert wird?

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') 

Die Ergebnisse sind:

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"} 

Wie ich schon verstanden, der Wert von DEFAULT_VALUE sollte nicht nach dem Aufruf append_new_value Methode geändert werden.

Könnt ihr mir helfen, diesen Fall zu erklären?

+0

Die Konstante ändert sich nicht. Das Objekt, auf das die Konstanten verweisen. Ruby ist keine rein funktionale Sprache, Objekte dürfen sich ändern. –

Antwort

0

Erstens hat Ruby nicht die Vorstellung von Konstanten, wie Sie es von anderen Sprachen erwarten würden. Ruby-Konstanten können Werte ändern. Wenn Sie angeben möchten, dass ein Objekt in Ruby nicht mutiert werden soll, müssen Sie die Methode Object#freeze verwenden.

Dann gibt es die Frage von Ruby, die Methodenargumente als Referenz oder als Wert übergeben. Man könnte sagen, dass Ruby im traditionellen Sinne pass-by-value ist. In Ruby sind alle Variablen Verweise auf Objekte. Wenn Sie also ein Objekt an eine Methode übergeben, wird es tatsächlich mutiert.

Wenn Sie schnelle Gewinne in der Unveränderlichkeit suchen, überprüfen Sie Object#dup.

+0

'dup' erzeugt nur eine seichte Kopie, d.h.' DEFAULT_VALUE [: first_key] 'und' DEFAULT_VALUE.dup [: first_key] 'beziehen sich immer noch auf das gleiche Array. – Stefan

+0

@Stefan du hast Recht. Nicht anwendbar in diesem Beispiel, ich erwähnte es nur als Referenz. – gkats

Verwandte Themen