What's the easiest way to check if param[:x][:y] exists?

J

Joshua Muheim

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
 
S

Shadowfirebird

It looks to me as if you should be able to check for nil.

foo( param[:x][:y] ) unless (param[:x][:y] == nil)

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
 
D

David A. Black

Hi --

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? ;-)

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
 
J

Joshua Muheim

Shadowfirebird said:
It looks to me as if you should be able to check for nil.

foo( param[:x][:y] ) unless (param[:x][:y] == nil)

I tried it on IRB, but it doesn't seem to work.
 
S

Shadowfirebird

Sorry, you're right:

irb(main):001:0> a = {:a=>{:x=>1}}
=> {:a=>{:x=>1}}
irb(main):003:0> p a[:a][:x]
1
=> nil
irb(main):004:0> p a[:a][:y]
nil
=> nil
irb(main):005:0> p a[:b][:x]
NoMethodError: undefined method `[]' for nil:NilClass
from (irb):5

David's *much* smarter than me, so listen to him...


It looks to me as if you should be able to check for nil.

foo( param[:x][:y] ) unless (param[:x][:y] == nil)

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
 
S

Stefano Crocco

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

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
 
J

Joshua Muheim

David said:
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... ;-)
 
T

Tommy Morgan

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.

It looks to me as if you should be able to check for nil.

foo( param[:x][:y] ) unless (param[:x][:y] == nil)

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
 
P

Pit Capitain

2008/8/12 David A. Black said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top