As Ruby developers, we all come across situations when you have to deal with some uncertain values or methods in your code. And this happens:
foo && foo.bar && foo.bar.baz && foo.bar.baz.qux
It’s ugly, right? Well, if we are using Rails then we can fix the problem by simply rewriting it like this:
foo && foo.try(:bar).try(:baz).try(:qux)
This solutions\ is more elegant but still not ideal.
Well, all of you that suffered from this problem can now celebrate, as Ruby is getting it’s own safe navigation operator!
And it will look like this:
This solution is small, easy and beautiful!
One thing to keep in mind though – it not an equivalent for try. .? First check to see if foo is not nil and only then call baz on it and further down the chain. Here’s a test right from Ruby Core code to demonstrate how it works. To rephrase a popular quote:
“A code is worth a thousand words”
s = Struct.new(:x, :y)
o = s.new("x")
o.?x = 6
o.?x *= 7
Of course, that doesn’t mean that we all should go raving about, with this new operand all over our codebase. Using nil?, empty? and present? almost always point to a code smells and .? can also became the case. But at least we’ll have an elegant and idiomatic method in our Ruby toolbox when we need it.
And that’s a good thing!
P.S. Right now .? is available in Ruby 2.3.0-dev version. Unless something changes will see it soon. If not – Ruby 3.0 is best bet for sure.