5

I have this code:

$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]

And this is the output:

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

Why isn't the output:

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

?

Turnsole
  • 3,422
  • 5
  • 30
  • 52

2 Answers2

5

With $ze[5][0] = xxx you are first calling the getter [] of $ze, then calling the setter []= of $ze[5]. See Hash's API.

If $ze does not contain a key, it will return its default value that you initialized with 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'

You are not adding anything to $ze but you are adding key/value pairs to its default hash. That is why you can do this too. You will the same result as $ze[5].

puts $ze[:do_not_exist]
# => {0=>"one", 1=>"two"}
oldergod
  • 15,033
  • 7
  • 62
  • 88
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

Execution :

$ 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"}}
BernardK
  • 3,674
  • 2
  • 15
  • 10