3 ms·
It's in deep nesting like that that such an operator really comes into its own. If you only use it for single cases, it really isn't worth it. In the article
by deckiedan 11y ago
It's in deep nesting like that that such an operator really comes into its own. If you only use it for single cases, it really isn't worth it.
In the article the 'problem' code is:
if u && u.profile && u.profile.thumbnails && u.profiles.thumbnails.large
do_something_with(u.profiles.thumbnails.large)
fi
which repeats u 5 times, and the entire u.profiles.thumbnails.large twice!
which would be replaced by only asking once.
even worse (although somewhat clearer, perhaps) is what I've occasionally seen:
if u
if u.profile
if u.profile.thumbnails
if u.profile.thumbnails.large
do_something_with(u.profile.thumbnails.large)
end
end
end
end
And even the super verbose version there still can raise exceptions when you get slightly mad data - say you decode some JSON which has u.profile.thumbnails as "null" (a string) rather than actually a null. asking
if u.profile.thumbnails
will be true - but when you request u.profile.thumbnails.large, you blow up.
You can achieve similar effects using only exceptions, but there's a good argument for using exceptions only for exceptional circumstances.
begin
do_something_with(u.profile.thumbnails.large)
rescue NoMethodError #or similar
# oh no!
end
which (alas) also will catch all noMethodErrors in do_something_with. So you then end up with
begin
tmp = u.profile.thumbnails.large
rescue
tmp = nil
end
if tmp
do_something(tmp)
end
which is super ugly.
I may have got details wrong - not being a rubyist, but I think this is the general gist of where a nestable operator makes much much cleaner code, which catches more errors.
- vidarh 11y agoAnd it's worth pointing out that the above is also slow whether you depend on exceptions or just the long if version, and depends on having methods with no side-effects, as several methods gets called multiple times. As far as I see the proposed version will work equivalent to assigning the result of each method invocation to a temporary, and doing the next check on that, which gets far more ugly if you have to write it out