Dans ce qui suit, input_1 change:
def method_2(a) a = ["new value"] end input_2 = [] method_2(input_2) input_2 #=> []
Dans ce qui suit, input_2 ne change pas:
def method_1(a) a << "new value" end input_1 = [] method_1(input_1) input_1 #=> ["new value"]
Pourquoi input_1 change-t-il alors que input_2 ne change pas?
3 Réponses :
Avec un peu de simplification, nous pouvons dire qu'une variable dans Ruby est une référence à une valeur. Dans votre cas, la variable a contient une référence à un tableau.
a ( a.append ) modifie la valeur stocké dans la variable a . La référence n'est pas modifiée, mais la valeur l'a fait. C'est le cas de method_1
def method_2(a)
a = ["new value"]
end
input = []
method_2(a)
L'affectation = change la référence stockée dans une variable - elle commence à pointer vers un valeur différente. Les références sont copiées lorsqu'elles sont transmises à une méthode. Pour cette raison, lorsque vous appelez
def method_1(a)
a << "new value"
end
Vous ne modifiez qu'une référence stockée dans a qui est locale à la méthode, sans aucune modification de la référence stockée dans input ni à la valeur (et au tableau de [] ) qui est pointé par cette référence.
Notez que si l'appel était changé en input_2 = method_2 (input_2) , la nouvelle référence générée par method_2 serait affectée à input_2 depuis les méthodes Ruby renvoie le résultat de leur dernière évaluation.
Cela se résume à Ruby en utilisant "pass-reference-by-value".
Le cas exact que vous rencontrez est décrit dans cet excellent article de blog .
Dans method_1 , vous modifiez la valeur d'un objet vers lequel pointent deux variables différentes ( input_1 et a ). p>
Dans method_2 , vous réaffectez un objet complètement nouveau à l'une des deux variables ( a ).
Pourquoi
input_1change alors queinput_2ne change pas?
La réponse très simple à cette question est que votre prémisse est fausse. input_1 ne change pas. L'objet auquel input_1 fait référence change, mais c'est quelque chose de complètement différent de input_1 . Le nom d'une chose n'est pas identique à la chose elle-même. (En dehors de la sorcellerie.)
Quelle est votre question exactement? Vous vous attendez à ce que la valeur de l'entrée soit
['new value']les deux fois?Pourquoi change input_1 alors que input_2 ne change pas?
le concept est appelé «mutabilité».
method_2assigne simplement une nouvelle variable avec le même nom que l'autre.