I recently learned that you can use rescue
on a line of code in case something goes wrong on that line (see http://www.rubyinside.com/21-ruby-tricks-902.html Tip #21). I have some code that used to look like this:
if obj['key'] && obj['key']['key2'] && obj['key']['key2']['name']
name = obj['key']['key2']['name']
else
name = ''
end
With the rescue
method, I believe I can change that code into something like this:
name = obj['key']['key2']['name'] rescue ''
If a nil exception is thrown at any level of accessing the hash, it should get caught by the rescue and give me '', which is what I want. I could also choose to set name to nil
if that were the desired behavior.
Is there any known danger in doing this? I ask because this seems too good to be true. I have so much ugly code that I'd love to get rid of that looks like the first code example.
A raised exception can be rescued to prevent it from crashing your application once it reaches the top of the call stack. In Ruby, we use the rescue keyword for that. When rescuing an exception in Ruby, you can specify a specific error class that should be rescued from.
The method definition itself does the work of begin , so you can omit it. You can also do this with blocks. Now, there is one more way to use the rescue keyword without begin .
Ruby also provides a separate class for an exception that is known as an Exception class which contains different types of methods. The code in which an exception is raised, is enclosed between the begin/end block, so you can use a rescue clause to handle this type of exception.
The code between “begin” and “rescue” is where a probable exception might occur. If an exception occurs, the rescue block will execute. You should try to be specific about what exception you're rescuing because it's considered a bad practice to capture all exceptions.
Reads good! But it will hit your performance. In my experience rescue
is much slower when triggered and slightly slower when it's not. In all cases the if
is faster. Other thing to consider, is that exceptions shouldn't be expected and you kind of are with this code. Having a hash so deeply nested might be a good smell that a refactoring is nede
This specific example can now be achieved with Ruby 2.3's dig method.
name = obj.dig 'key', 'key2', 'name'
This will safely access obj['key']['key2']['name']
, returning nil if any step fails.
(In general, it's usually advised to use exceptions only for real, unanticipated, errors, though it's understandable in an example like this if the syntax makes it cumbersome.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With