Okay, I got confused by how ruby passes it's arguments to a function. I've read in the documentation that ruby passes by value, but in my case it looks like it's passing by referance
Here's the problem:
好吧,我被Ruby将其参数传递给函数的方式搞糊涂了。我在文档中读到Ruby是通过值传递的,但在我的例子中,它看起来像是通过引用传递的,问题是:
def buble_sort(arr)
unordered = true
while unordered
unordered = false
for i in (1..arr.size-1)
if(arr[i-1] > arr[i])
arr[i-1], arr[i] = arr[i], arr[i-1]
unordered = true;
end
end
end
arr
end
Calling this method shouldn't modify the arr value, since ruby passes it by value. But in my case, it does modify the original array. Why?
Code:
调用此方法不应修改arr值,因为Ruby通过值传递它。但在我的例子中,它确实修改了原始数组。为什么?代码:
p "#{arr} before sort" # => "[85, -4, 1, 2, 55, 23, 0] before sort"
p buble_sort(arr) # => [-4, 0, 1, 2, 23, 55, 85]
p "#{arr} after sort" # => "[-4, 0, 1, 2, 23, 55, 85] after sort"
更多回答
A reference is a value. Unless you copy the array you're operating on the same array.
引用是一个值。除非您复制数组,否则您就是在同一数组上操作。
You need to dup an object or to construct a new one, e. g. def buble_sort(*arr)
您需要复制一个对象或构造一个新对象,例如def Buble_Sort(*arr)
This doesn't have anything to do with pass-by-reference or pass-by-value. The difference between the two can only be observed when you re-bind the reference, but you never do that, so the results are actually the same regardless of whether Ruby is pass-by-reference or pass-by-value. What you are seeing is simply mutable state. Ruby is not a purely functional language, it has mutable state and side-effects. This is an example of mutable state, and this is an example of why it should be avoided.
这与按引用传递或按值传递没有任何关系。只有在重新绑定引用时才能观察到两者之间的差异,但您从未这样做过,因此无论Ruby是按引用传递还是按值传递,结果实际上都是相同的。您所看到的只是简单的可变状态。Ruby不是一种纯粹的函数式语言,它有可变的状态和副作用。这是可变状态的一个例子,也是为什么应该避免它的一个例子。
To understand that, you have to make a distinction between a variable and what this variable stands for. Consider the following example :
要理解这一点,您必须区分变量和这个变量所代表的含义。请考虑以下示例:
items = [1, 2, 3]
# the variable items points to an array we just instantiated
items = [4, 5, 6]
# items now points to a new array
If ruby passed arguments by reference, doing so within a method with an argument it received would also make the variable exposed to the method by the caller point to a new location
如果Ruby通过引用传递参数,则在带有其接收到的参数的方法中这样做还会使调用方向该方法公开的变量指向新位置
items = [1, 2, 3]
def my_method array
array = [4, 5, 6]
return array
end
my_method(items) # --> [4, 5, 6]
items # --> [1, 2, 3]
# if ruby passed arguments by reference, items would now be [4, 5, 6]
Now ruby passes arguments by value, but the value you received is a reference to the same location in memory as the one the called passed you. In other words, you don't get a clone, a dup, but the same object.
现在Ruby通过值传递参数,但是您收到的值是对内存中与调用传递给您的位置相同的位置的引用。换句话说,你得到的不是克隆,不是DUP,而是相同的对象。
items = [1, 2, 3]
def my_method array
array << 4
return array
end
my_method(items) # --> [1, 2, 3, 4]
items # --> [1, 2, 3, 4]
If you want your method to have no side-effect on its arguments you can clone them.
如果您希望您的方法对其参数没有副作用,您可以克隆它们。
Almost everything in ruby is an object. In methods, objects are passed by reference.
Ruby中的几乎所有东西都是对象。在方法中,对象通过引用传递。
a = [1,2,3,4]
a is a variable whose value is the reference of an array.
A是一个变量,其值是数组的引用。
def someMethod(b)
#...
end
someMethod(a)
here a's value is passed that is reference of the array, and it is received in the variable b. That means a and b both are having value as reference of the array.
在这里,a的值被传递为数组的引用,它在变量b中接收。这意味着a和b都有值作为数组的引用。
def someMethod(b)
b = [4,5,6]
end
here b is assigned a new value that is reference to the new array. a still has the reference of the original array as value.
这里,为b分配了一个引用新数组的新值。A仍然将原始数组的引用作为值。
Arrays are mutable, meaning we can change the content of array object.
数组是可变的,这意味着我们可以更改数组对象的内容。
a = [1,2,3]
a[1]= 5
puts a
will print [1,5,3]
将打印[1,5,3]
All primitive objects like numbers are immutable objects.
所有像数字这样的基元对象都是不可变的对象。
a =5
a stores the reference of an integer object which contains value 5.
A存储包含值5的整数对象的引用。
a = a +1
now a stores the reference of an integer object which contains value 6. The object containing 6 is different than the object containing 5. The object containing 5 earlier, still contains 5 but its reference is not stored any where.
现在a存储包含值6的整数对象的引用。包含6的对象与包含5的对象不同。以前包含5的对象仍包含5,但其引用不存储在任何位置。
更多回答
in Java, JavaScript and Ruby all variables are passed by value. Since every variable holds the reference of the object, called methods receives the copy of the reference. now there are two variables, one holding reference to the original object and second also holding the reference of the same object. Any object mutation operation will be seen through both the variables. Because same reference is copied and assigned to the method parameter it is called passed by reference.
在Java、JavaScript和Ruby中,所有变量都是通过值传递的。由于每个变量都保存对象的引用,因此调用的方法会接收引用的副本。现在有两个变量,一个保存对原始对象的引用,另一个也保存对同一对象的引用。任何对象突变操作都将通过这两个变量来查看。由于复制了相同的引用并将其分配给方法参数,因此它是通过引用传递的。
我是一名优秀的程序员,十分优秀!