Манипулирование массивом Ruby внутри метода - PullRequest
0 голосов
/ 08 января 2019

В дальнейшем input_1 изменяется:

def method_1(a)
  a << "new value"
end

input_1 = []
method_1(input_1)
input_1 #=> ["new value"]

В дальнейшем input_2 не изменяется:

def method_2(a)
  a = ["new value"]
end

input_2 = []
method_2(input_2)
input_2 #=> []

Почему input_1 меняется, а input_2 не меняется?

Ответы [ 3 ]

0 голосов
/ 08 января 2019

Это сводится к Ruby с использованием «pass-reference-by-value».

Точный случай, с которым вы сталкиваетесь, описан в этом отличном сообщении в блоге .

Суть:

В method_1 вы меняете значение объекта, на который указывают две разные переменные (input_1 и a).

В method_2 вы переназначаете совершенно новый объект одной из двух переменных (a).

0 голосов
/ 08 января 2019

Почему input_1 меняется, тогда как input_2 не меняется?

очень простой ответ на этот вопрос заключается в том, что ваша предпосылка ошибочна. input_1 не меняется. Объект, который input_1 ссылается на , изменяется, но это нечто совершенно отличное от input_1. Название вещи не совпадает с самой вещью. (Вне колдовства.)

0 голосов
/ 08 января 2019

С небольшим упрощением можно сказать, что переменная в Ruby является ссылкой на значение. В вашем случае переменная a содержит ссылку на массив.

a << (a.append) изменяет значение , хранящееся в переменной a. Ссылка не изменилась, но значение изменилось. Это случай method_1

def method_1(a)
    a << "new value"
end

Назначение = изменяет ссылку, хранящуюся в переменной - она ​​начинает указывать на другое значение. Ссылки копируются при передаче методу. Из-за этого, когда вы звоните

def method_2(a)
    a = ["new value"]
end
input = []
method_2(a)

Вы изменяете только ссылку, хранящуюся в a, которая является локальной для метода, без каких-либо изменений в ссылку, сохраненную в input, или в значение (и массив []), на которое указывает эта ссылка.

...