5
votes

Manipulation du tableau Ruby à l'intérieur de la méthode

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 commentaires

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_2 assigne simplement une nouvelle variable avec le même nom que l'autre.


3 Réponses :


6
votes

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.


1 commentaires

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.



7
votes

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 .

L'essentiel:

Dans method_1 , vous modifiez la valeur d'un objet vers lequel pointent deux variables différentes ( input_1 et a ).

Dans method_2 , vous réaffectez un objet complètement nouveau à l'une des deux variables ( a ).


0 commentaires

2
votes

Pourquoi input_1 change alors que input_2 ne 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.)


0 commentaires