Ruby变量(数组)赋值误解(使用push方法)

我发现了我对Ruby或编程理论或两者的理解中的一个缺陷。 看看这个代码:

#!/usr/bin/ruby -w @instance_ar = [1,2,3,4] local_ar = @instance_ar local_ar_2 = local_ar ### irrelevant_local_ar = [5,6,7,8] ### for i in irrelevant_local_ar local_ar_2.push(i) end count = 0 for i in local_ar_2 puts "local_ar_2 value: #{i} and local_ar value: #{local_ar[count]} and @instance_ar value: #{@instance_ar[count]}\n" count += 1 end 

输出是

 local_ar_2 value: 1 and local_ar value: 1 and @instance_ar value: 1 local_ar_2 value: 2 and local_ar value: 2 and @instance_ar value: 2 local_ar_2 value: 3 and local_ar value: 3 and @instance_ar value: 3 local_ar_2 value: 4 and local_ar value: 4 and @instance_ar value: 4 local_ar_2 value: 5 and local_ar value: 5 and @instance_ar value: 5 local_ar_2 value: 6 and local_ar value: 6 and @instance_ar value: 6 local_ar_2 value: 7 and local_ar value: 7 and @instance_ar value: 7 local_ar_2 value: 8 and local_ar value: 8 and @instance_ar value: 8 

问题A:如何push送到local_ar_2更改另外两个数组? 我对局部变量的理解是,一旦它们被创建,它们不应该影响任何其他变量,因为它们是本地变量。

问题B:我怎样才能避免这样的事情发生? 来自C和Perl,这只是让我大吃一惊。

Ruby使用引用! 记在脑子里。 如果你想要一份副本,你必须这样做:

 @instance_ar = [1,2,3,4] local_ar = @instance_ar.clone local_ar_2 = local_ar.clone 

编辑:

例子:

 a = ["a", "b", "c"] b = a[0] b = "d" # We assign a new object to b! 

a是:=> [“a”,“b”,“c”]

但:

 a = ["a", "b", "c"] b = a[0] b[0] = "d" # We are working with the reference! a is: => ["d", "b", "c"] a = "hello" b = a b += " world" # Is the same as b = b + " world", we assign a new object! 

a是:=>“你好”

但:

 a = "hello" b = a b<<" world" # We are working with the reference! 

a是:=>“你好世界”

 a = "abc" b = a b[0] = "d" # we are working with the reference 

a是:=>“dbc”

你可以在这里阅读有关它的所有内容: http : //ruby-doc.org/docs/ProgrammingRuby/ 。 在页面底部几乎向下滚动到“变量”。

在Ruby中,您不是“创建变量”,而是创建对象(在您的情况下是一个数组),并将它们分配给变量。 因此,在您的示例中,您有一个具有两个名称的单个数组local_arlocal_ar_2 。 之后你改变了对象,而不是变量(它们都指向同一个改变的对象)。

你说你来自C,看看这个例子:

 int a[5]; int * b; a[0] = 10; a[1] = 20; b = a; b[1] = 5; printf("%d", a[1]); 

会打印什么号码? 它与Ruby代码中发生的情况大致相同。

一个注意事项:使用for for迭代数组在Ruby中不是惯用的。 通常使用:

 local_ar_2.each_with_index do |i, count| puts "local_ar_2 value: #{i} and local_ar value: #{local_ar[count]} and @instance_ar value: #{@instance_ar[count]}\n" end