Try is useless
Object#try
from ActiveSupport is a code smell.
What developers need in the vast majority of cases is &.
or Object#try!
.
What is the difference between those? x.try(:method)
returns nil
when x
is a non-nil object that does not respond to :method
. On the other hand,
x&.method
fails with NoMethodError
in such cases.
Why is this difference important? It is important because of the reasons is
outlined in the previous post about flatten
. try
is very vague. It declares
that you don’t know what kind of object is the receiver. If you pass the wrong
kind of object, for example something that does not respond to the passed
message, try
will just silently hide this from you. This is bad because it
just postpones the error until later. It is always better to fail ASAP (at
compile time, if you wish), than to delay the error and pretend that everything
is fine.
Here is an example.
What happens there if someone passes {namespace: :core}
instead of {namespace: 'core'}
,
perhaps because of a bug? The poor user will just get confused why :namespace
param is ignored, and she will need to investigate the source code to understand
what happens there.
On the other hand, if we use try!
there, the code will rightfully blow up
with a nice message:
There are many more examples like this:
Again, the difference between try!
and try
is the difference between confident
code and sloppy code.
And by the way, try!
is more performant than try
on average.
There are cases when try
is really needed,
but they are rare.