Search code examples
ruby-on-railsrubylanguage-designmonkeypatching

Is there a reason Ruby/Rails has not made nested indexing safe?


A feature of ruby that I've always considered nice is the nil default for indexing/hash lookup, e.g.

[1, 2, 3][42]         # => nil
{ foo: :bar }[:spam]  # => nil

Is there a reason why, in Ruby's design or Ruby on Rails' core extensions, this has not been extended to work for nested lookups (rather than throwing NoMethodError: undefined method '[]' for nil:NilClass)?

For example:

{ foo: [1, 2, 3] }[:bar][0][:baz]   # => nil
[[[]]][12][1][1]                    # => nil

In my, perhaps nieve, understanding it would be as simple as:

class NilClass
  def [](_); end
end

Solution

  • Some languages, like Objective-C, make method calls on a nil object return nil so these sorts of errors melt away.

    Rails has always taken the path of having a "whiny nil" where any method calls hard fail. This has become expected behaviour.

    If you want to patch your NilClass, do it completely:

    def NilClass
      def method_missing(*args)
        # Do nothing, return nil
      end
    end
    

    You can add this in config/initializers to suppress errors, but be warned, this may hide legitimate problems and make your application perform in unpredictable ways. For example. nil.id actually returns a value.