2010-09-08 58 views
2

我發現了我對Ruby或編程理論或兩者兼有的缺陷。看看這段代碼: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 

問題答:如何pushlocal_ar_2改變其他兩個陣列?我對局部變量的理解是,一旦創建它們,它們就不應該影響任何其他變量,因爲它們是本地變量。

問題B:如何避免發生這種情況?來自C和Perl,這只是讓我頭腦發熱。

回答

9

紅寶石與參考!記住這一點。如果你想要一個副本你必須要做得像:

@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」

你可以閱讀關於它的一切e:http://ruby-doc.org/docs/ProgrammingRuby/。向下滾動到頁面底部的「變量」。

3

在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來遍歷數組在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 
+0

我喜歡你把第一句話的方式,非常簡潔和內容豐富。 – LukeP 2015-04-24 19:42:59