Search code examples
ruby-on-railsrubynull-checksafe-navigation-operator

Ruby's safe navigation operator (&.) not working as intended anymore after being in use on production code for years


I'm having this issue in production code that's been running for years without issue, where suddenly a lot of places where i use the &. operator is just crashing. So I'm wondering if it's not just an environment variable or some kind of interpreter option. It's running Ruby 2.5.9 on Rails 5.1.4

With the following line as an example

s.item.tags.select { |tag| tag.name }

item is nil, so trying to execute this line will give me the following error

undefined method `tags' for nil:NilClass

So in theory by using the &. operator

s.item&.tags.select { |tag| tag.name }

I should not be getting this error but I am

private method `select' called for nil:NilClass

It seems to me like it should stop at s.item&. and return nil, but it keeps going.

If I add another &. it will just crash on the next one

s.item&.tags&.select { |tag| tag.name }.map { ... }
undefined method `map' for nil:NilClass

and so on.

--EDIT--

I should mention, what I'm assuming is happening is that there has never been a case where s.item was nil in the past so it has never crashed because of that. It seems that most of the errors were linked to that specific item being nil, probably not because of an environment variable or interpreter option.


Solution

  • Must be a data issue on your end - some new s records do not contain any of these relationships items->tags, instead of Ruby's safe navigation behavior changed on it's own in the same version (assuming no ruby version upgrades happen).

    Safe navigation in Ruby behaves that way. Even in Ruby's official documentation that is the noted behavior:

    Note that &. skips only one next call, so for a longer chain it is necessary to add operator on each level