From: Ross Bamford Date: 2006-09-28T06:57:19+09:00 Subject: Re: Accessing Nested Hashes Directly On Thu, 2006-09-28 at 02:05 +0900, atraver@gmail.com wrote: > Thanks for all the responses. > > Here is the method I ended up with after looking over everything, just > in case this topic is searched for in the future: > > def get_value(object, *path) > for item in path > break unless object > object = object ? object[item.to_s] : nil > end > > return object.kind_of?(String) ? object.strip : object > end > > This might be a little more verbose than some of the solutions (also, > Ross, your "inject" solution didn't seem to work out although I'm sure > it would with some tweaking). However, it ends up doing exactly what I > need it to do: get the value or return nil, in a quick-and-dirty way. Hmm, out of interest, what didn't work out about it? Maybe I misunderstand what you're doing, but (if you ignore the Hash-extending silliness) it seems to work the same. require 'test/unit' def get_value(object, *path) for item in path break unless object object = object ? object[item.to_s] : nil end return object.kind_of?(String) ? object.strip : object end def my_get_value(hsh, *path) path.inject(hsh) { |obj, item| obj[item.to_s] || break } end class TestGetValue < Test::Unit::TestCase def setup @h = { 'name' => { 'first' => 'Ross' }, 'contact' => { 'phone' => { 'office' => '345345' } } } end def test_it assert_equal get_value(@h, :name, :first), my_get_value(@h, :name, :first) assert_equal get_value(@h, :name, :middle), my_get_value(@h, :name, :middle) assert_equal get_value(@h, :contact), my_get_value(@h, :contact) assert_equal get_value(@h, :contact, :phone, :office), my_get_value(@h, :contact, :phone, :office) end end # -> 1 tests, 4 assertions, 0 failures, 0 errors The only thing I changed here is adding to_s on the item in my version, so I could use the same hash to test both while keeping symbol keys. -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk