Hi all
In PHP I can simply check whether $param['x']['y'] exists regardless
whether $param['x'] exists or not.
In Rails I get a NoMethodError when using
if param[:x][:y]
..
end
when param[:x] is nil. So I always have to use
if param[:x] and param[:x][:y]
..
end
but I think that's not very beautiful - think about a case where I have
to check whether param[:a][:b][:c][:d][:...] exists or not!
Maybe there's a cooler way to do this? ;-)
Thanks
Josh

Hi --
On Wed, 13 Aug 2008, Joshua Muheim wrote:
> when param[:x] is nil. So I always have to use>> if param[:x] and param[:x][:y]> ..> end>> but I think that's not very beautiful - think about a case where I have> to check whether param[:a][:b][:c][:d][:...] exists or not!>> Maybe there's a cooler way to do this? ;-)
Yes: design your data structures with classes and modules and methods,
instead of quintuply-nested hashes :-) But if you want to have a hash
that automatically inserts a hash for an unknown key, you can do:
func = lambda {|h,k| h[k] = Hash.new(&func) }
hash = Hash.new(&func)
I think that's the OK version.... You can also rescue NoMethodError,
though that's kind of fuzzy with lots of nesting.
David

David A. Black wrote:
>> Maybe there's a cooler way to do this? ;-)>> Yes: design your data structures with classes and modules and methods,> instead of quintuply-nested hashes :-)
You're right, I just saw that I don't need such a nested hash... ;-)

On Tuesday 12 August 2008, Joshua Muheim wrote:
> when param[:x] is nil. So I always have to use> Thanks> Josh
You can use the rescue modifier, like this:
if (param[:x][:y] rescue nil)
...
end
The expression in brackets will return the value of param[:x][:y] but if
param[:x][:y] raises an exception derived from StandardError (like
NoMethodError), the exception will be caught by the rescue modifier, and
the
statement to the right of rescue (nil) will be returned.
I hope this helps
Stefano

> foo( param[:x][:y] ) unless (param[:x][:y] == nil)
That only works if param[:x] exists. It's also not perfect, since
[aram[:x][:y] can return a non-nil value if param[:x] exists but is
not an array... so you probably need to check for that case also.
To my knowledge, the only way you could handle this easily would be to
rescue the NoMethodError as follows:
param[:x][:y] rescue NoMethodError { nil } # return nil if
NoMethodError is raised
Although that's tricky too, as depending on the nature of your object
structure, you may catch a NoMethodError you didn't intend to catch.
Hope that helps.
--Tommy M.

2008/8/12 David A. Black <dblack@rubypal.com>:
> But if you want to have a hash> that automatically inserts a hash for an unknown key, you can do:>> func = lambda {|h,k| h[k] = Hash.new(&func) }> hash = Hash.new(&func)
David, hashes like this don't solve Josh's problem. He wants two
conflicting things:
1) param[:x][:y] should be false or nil, so that you can use it as a
condition
2) you should be able to nest arbitrarily deep, for example
param[:x][:y][:z]
If Josh really wanted to do that, he'd have to define FalseClass#[] or
NilClass#[], but as you have written he'd better change his data
structures.
Regards,
Pit