Using that operator a single time or whatnot seems handy, but chaining it like that just seems like poor practice to me.
Using that operator a single time or whatnot seems handy, but chaining it like that just seems like poor practice to me.
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.
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
The whole motivation of the operator is for chaining.