This is maybe a more cosmetic problem, but I find it really annoying as I always end up with some ugly code. And readability is always important, right?
I want to check if a value exists in a hash within a hash. So what I do is this.
already_exists_data[:data][:user_id]
But that can get me a nullpointer exception if :data is nil and checking :data might give me a nullpointer if already_exists_data is nil. So what I end up with is this:
if already_exists_data && already_exists_data[:data] && already_exists_data[:data][:user_id]
# Do stuff
end
Now that's some nasty looking code. Perhaps I should modify the hash to be an object instead. But I keep bumping in to this problem sometimes and was wondering how you guys confront it.
I'm currently coding in Ruby but I've had this problem with multiple other languages.
If I ask my butler to pick up the box of chocolates on the dining room table in Victoria street 34, I ask him just that. I don't want to say: Go find Victoria Street, and, if you find it, please look for number 34, and if you find it ...
I can do that because he catches his own errors: if he doesn't find the street he will just return empty-handed.
So you should use a try
with an empty exception handler. In pseudo-code:
try {chocolates = streets("Victoria")(34)("dining room")("table")}
In languages (like ruby
, with some homespun syntactic sugar) where blocks are expressions you might write:
if try {already_exists_data(data)(user_id)}
do_stuff
The language itself can also help: in perl
, $streets{Victoria}[34]{dining_room}{table}
is undefined when e.g. $streets
is. Of course, your butler may come home empty-handed for years before you discover that the address is wrong. The try
block solution - and your if .. && ....
- have the same drawback: only use them when you really don't care if Victoria Street has a number 34 or not.