From: "David A. Black" Date: 2007-11-04T05:48:42+09:00 Subject: Re: x=[]; x[:bla][:some_key] does not work? Hi -- On Sun, 4 Nov 2007, Jano Svitok wrote: > On 11/3/07, Joshua Muheim wrote: >> Hi all >> >> PHP lets me easily create multidimensional hashes using the following >> syntax: >> >> x = array(); >> x["bla"]["some_key"] = true; >> >> Is Ruby not capable of doing this? >> >> x = [] >> x[:bla][:some_key] = true >> >> gives me a nil error! > > As David said, if you want to create hashes, you have to create Hashes ;-) > > Then, you can tell Hash.new what is the default value, so you can > create hash, that will contain by default empty hashes: > > x = Hash.new { Hash.new } > > This will add an "automatic" two level hash. I don't know quickly how > to make this indefinitly deep, you can at least repeat the pattern. > > Please note that it is not enough to write Hash.new { {} } as the > inner will create one particular Hash instance, that all keys will > reference. You need Hash.new to create a new hash for each key. That's not quite right. The only-one-object thing is when you do this: h = Hash.new({}) If you use a block, it gets executed each time -- so in your example, a new hash would get created. However, it's important to remember that what you're setting is the default value (or behavior) for *non-existent* keys. So if you do: h = Hash.new { {} } a = h[1] a is now a hash, but h still has no keys. The block is automatically passed the hash itself, and the key: h = Hash.new {|hash,key| # do stuff with hash and key } and you can use that fact to actually add the key to the hash. David -- Upcoming training by David A. Black/Ruby Power and Light, LLC: * Advancing With Rails, Edison, NJ, November 6-9 * Advancing With Rails, Berlin, Germany, November 19-22 * Intro to Rails, London, UK, December 3-6 (by Skills Matter) See http://www.rubypal.com for details!