2011-12-16 31 views
-1

以下兩種情況看起來相似,但結果不同。有趣的是,也許有人會犯這樣的錯誤。關於在紅寶石散列中賦值的奇怪之處

CASE1

class A 
    def initialize 
     @a = @b = @c = @d = @e = {} 
     @e["e"] = "eeeeee" 

     puts @a 
     puts @b 
     puts @c 
     puts @d 
     puts @e 
    end 
end 
a = A.new 

給出:

{"e"=>"eeeeee"} 
{"e"=>"eeeeee"} 
{"e"=>"eeeeee"} 
{"e"=>"eeeeee"} 
{"e"=>"eeeeee"} 

CASE 2

class B 
    def initialize 
     @a = @b = @c = @d = @e = {} 
     @e = {"e" => "eeeeee"} 

     puts @a 
     puts @b 
     puts @c 
     puts @d 
     puts @e 
    end 
end 
b = B.new 

給出:

{} 
{} 
{} 
{} 
{"e"=>"eeeeee"} 

編輯

結果是CASE 1和CASE 3之間的不同,但它們以相同的方式分配值。

CASE 3

class C 
    def initialize 
     @a = {} 
     @b = {} 
     @c = {} 
     @d = {} 
     @e = {} 
     @e["e"] = "eeeee" 

     puts @a 
     puts @b 
     puts @c 
     puts @d 
     puts @e 
    end 
end 

c = C.new 

#the result of case 3 
{} 
{} 
{} 
{} 
{"e"=>"eeeee"} 
+0

這是一個問題嗎?你正在做兩件完全不同的事情。有什麼奇怪的? – 2011-12-16 01:49:50

回答

1

不同的行爲是因爲ruby沒有完成分配的完整副本。

您可以在控制檯中探索此操作。嘗試

a = {"foo" => "bar"} 
b = a     # b and a are references to the same hash object 
a["foo"] = "baz"  # changes the underlying hash 
b      

你得到=> {"foo"=>"baz"}因爲你所做的是創建一個哈希對象並綁定a到該對象,那麼勢必b同一對象爲a(即,它們是同一個對象都引用) 。因此,當您更改a時,您將更改基礎對象,並且當您檢查b時,您會看到相同的更改!這與您在CASE 1中執行操作時發生的情況相同(b = a = {"foo" => "bar"}

在您的CASE 2中,您將以同樣的方式將所有5個變量綁定到相同的哈希對象。分配@e到一個新的哈希值。這是因爲如果你這樣做

b = a = {"foo" => "bar"} 
b = {"foo" => "baz"}  # replacing b with a reference to a new hash object 

你的情況3,你要綁定的所有5個變量獨立散列的對象,所以,當你改變一個是相互獨立的,一拉

a = {"foo" => "bar"} 
b = {"foo" => "bar"} # b and a reference independent hash objects 
b["foo"] = "baz" 

參見考試ple,http://ruby.about.com/od/advancedruby/a/deepcopy.htm

1

它沒有做 「同樣的事情」。 @e["e"] = "eeeeee"將密鑰["e"]設置爲多個變量指向的現有散列。 @e = {"e" => "eeeeee"}爲變量@e分配一個新的哈希值,它不會改變其他變量。