Ruby array manipulation inside method

回眸只為那壹抹淺笑 提交于 2019-12-19 19:55:09

问题


In the following, input_1 changes:

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

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

In the following, input_2 does not change:

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

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

Why does input_1 change while input_2 doesn't change?


回答1:


With a bit of simplification we can say that a variable in Ruby is a reference to a value. In your case variable a holds a reference to an array.

a << (a.append) mutates the value stored in variable a. The reference is not changed, but the value did. It's the case of method_1

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

Assignment = changes the reference stored in a variable - it starts to point to a different value. References are copied when passed to a method. Because of that when you call

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

You only change a reference stored in a that is local to the method, without any change to the reference stored in input nor to the value (and array of []) that is pointed by this reference.




回答2:


It boils down to Ruby using "pass-reference-by-value".

The exact case that you encounter is described in this excellent blog post.

The gist:

In method_1 you are changing the value of an object that two different variables (input_1 and a) are both pointing to.

In method_2 you are reassigning a completely new object to one of the two variables (a).




回答3:


Why input_1 changes whereas input_2 doesn't change?

The very simple answer to this question is that your premise is wrong. input_1 doesn't change. The object that input_1 references changes, but that is something completely different from input_1. The name of a thing is not the same as the thing itself. (Outside of witchcraft.)



来源:https://stackoverflow.com/questions/54090261/ruby-array-manipulation-inside-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!