2012-12-25 22 views
5

mam ten kod:Dlaczego ta rubinowa mieszanka nie jest taka, jak myślałem?

$ze = Hash.new(Hash.new(2)) 

$ze['test'] = {0=> 'a', 1=>'b', 3 => 'c'} 

$ze[5][0] = 'one' 
$ze[5][1] = "two" 

puts $ze 
puts $ze[5] 

I to jest wyjście:

{"test"=>{0=>"a", 1=>"b", 3=>"c"}} 
{0=>"one", 1=>"two"} 

Dlaczego nie jest wyjście:

{"test"=>{0=>"a", 1=>"b", 3=>"c"}, 5=>{0=>"one", 1=>"two"}} 
{0=>"one", 1=>"two"} 

?

+7

Nie używać zmiennych globalnych, są brzydkie! – Hauleth

Odpowiedz

5

Z $ze[5][0] = xxx jesteś pierwszy nazywając getter [] z $ze, następnie wywołanie seter []= z $ze[5]. Zobacz Hash's API.

Jeśli $ze nie zawiera klucza, zwróci wartość domyślną zainicjowaną przez Hash.new(2).

$ze[5][0] = 'one' 
# in detail 
$ze[5] # this key does not exist, 
     # this will then return you default hash. 
default_hash[0] = 'one' 

$ze[5][1] = 'two' 
# the same here 
default_hash[1] = 'two' 

Nie jesteś dodawania czegokolwiek do $ze ale dodawania par klucz/wartość do domyślnej hash. Dlatego też możesz to zrobić. Otrzymasz taki sam wynik, jak $ze[5].

puts $ze[:do_not_exist] 
# => {0=>"one", 1=>"two"} 
+0

Och! Nie zdawałem sobie sprawy, że możesz nawet zmodyfikować domyślny skrót. Dzięki. – Turnsole

1
h = Hash.new(2) 
print "h['a'] : "; p h['a'] 

$ze = Hash.new(Hash.new(2)) 
print '$ze[:do_not_exist] : '; p $ze[:do_not_exist] 
print '$ze[:do_not_exist][5] : '; p $ze[:do_not_exist][5] 

$ze = Hash.new{|hash, key| hash[key] = {}} 
$ze['test'] = {0=> 'a', 1=>'b', 3 => 'c'} 
$ze[5][0] = 'one' 
$ze[5][1] = "two" 
print '$ze : '; p $ze 

Wykonanie:

$ ruby -w t.rb 
h['a'] : 2 
$ze[:do_not_exist] : {} 
$ze[:do_not_exist][5] : 2 
$ze : {"test"=>{0=>"a", 1=>"b", 3=>"c"}, 5=>{0=>"one", 1=>"two"}}