Tag Cloud
python cli urwid elasticsearch aws ecs apache spark scala AWS EMR hadoop golang telegram bot webhooks ssl nginx digital-ocean emr apache pig datapipeline found.io elastic-cloud rails try capybara docker devops capistrano heka bigquery kafka protobuf vim iterm javascript emberjs git scripting dnsmasq bem frontend meteorjs meteorite heroku

Nil, Try & The Lonely Operator

Recently, I left a comment on one of my colleague’s PR and we had a discussion with him about the use of try vs the lonely operator &. and it led to a number of conclusions personally.

I used to use lots of .try. I’ve also come across codebases littered with it, be it in the presentation layer or in the models. From personal experience, I’ll say it’s pretty easy to end up with .try littered all around.

I was curious about when it shouldn’t be used, and if there were better alternatives.

The Obvious Scenario

Before the lonely operator was introduced, I used try in a 2 distinct scenarios.

The first obvious usecase: when I am not sure if the object that I are calling the method on could be a nil object or not. Obviously, calling any method on a nil object rightfully throws an error during runtime. Of course, I could use something like this to avoid the error.

user && user.name

And user.try(:name) yields the same result.

The Not So Obvious Scenario

Surprisingly, even when I don’t know what the object is and whether it even has that method defined or not, I still found myself using try. It still returns nil. It’s like this deceivingly good and lazy way to sidestep NoMethodError. But I find that this laziness, potentially leads to surprises (which obviously isn’t good).

# Either a guest user without a name, or a registered user with a name
some_user.try(:name)

The Lonely Operator

user&.name is equivalent to user && user.name and only this. It still throws a NoMethodError when the method doesn’t exist on the object. And that’s good for various reasons.

[]&.invalid_method # throws NoMethodError

In the event where I have no idea what the object is, it is a clear sign that I should spend the time to refactor the code so that the object class is deterministic and not rely on a .try to squirm out of the situation.

Another nice side effect is that, the lonely operator really doesn’t look great when I chain it. Being huge on aesthetics and coding styles, I just end up chaining less.

user&.name&.truncate(5) # this just looks clunky imo

All those .try(..).try(..)? I always knew I should be getting rid of those too, but it was just so safe. Law of Demeter literally screams at me every time.

I hope this post makes you think twice the next time .try chains comes to mind:P

comments powered by Disqus