loading...
Cover image for NoMethodError: undefined method for nil:NilClass... Explained

NoMethodError: undefined method for nil:NilClass... Explained

ben profile image Ben Halpern ・1 min read

This is a common Ruby error which indicates that the method or attribute for an object you are trying to call on an object has not been defined.

NoMethodError: undefined method SOME_METHOD for nil:NilClass

For example, the String class in Ruby has the method size (which is synonymous with length, so I can write...

greeting = "hello"
greeting.size
#=> 5

But loveliness does not exist for a string, so when I type it, I will get...

NoMethodError: undefined method loveliness for nil:NilClass

I find this will come up when I think I'm operating on an object with methods, but I'm actually operating on a hash with attributes.

my_hash[:loveliness]
# "very lovely" yay, this is a thing that exists!
my_hash.loveliness
# NoMethodError: undefined method loveliness nil:NilClass

Of course, because this is Ruby, we can actually define loveliness if we wanted to very easily by monkeypatching the String class.

class String

  def loveliness
    "very lovely"
  end

end

Now we know how lovely our string is. If I was mistaken or unclear, please feel free to add a comment to clarify anything here.

Happy coding ❤️

Posted on by:

ben profile

Ben Halpern

@ben

A Canadian software developer who thinks he’s funny. He/Him.

Discussion

markdown guide
 

This one tripped up me all the time when I was just starting out. While the error seems to be about the method, it's usually the object you're trying to call it on that is problematic somehow.

If the object is allowed to be nil, you want to check its presence before calling any method on it. For example:

coffee.drink_it if coffee.present? 

Or if you like concise code:

coffee&.drink_it 
# shorthand for `coffee && coffee.drink_it`
# which basically does the same thing as the present? check

Small nitpick about the example code in article: if my_hash was an actual hash, the error would say {:foo => :bar}:Hash instead of nil:NilClass.

 

Haha. Very basic but pesky one for beginners.
I can say nearly one third of SO questions are javascript version of this problem.

 
 

if we wanted to very easily by monkeypatching the String class

An often overlooked possibility in Ruby is defining methods on instances of a class (instead of monkey-patching the class itself):

s = "a string"
def s.loveliness
  "👋 Ben"
end

s.loveliness
#=> "👋 Ben"
"another string".loveliness
# NoMethodError (undefined method `loveliness' for "another string":String)

I have used variations [1] of this pattern on occasion to add a method to an object to satisfy some duck-typed interface without the hassle of defining a wrapper class (generally when writing temp code for refactorings or other things that don't need to survice for a long time). It's no coincidence that this looks like a class method definition (def self.loneliness) btw, as it's the same principle, i.e. specifying the object that gets the method added to its singleton class.

Another alternative would be using Refinements, but I don't see them much in the wild and haven't used them often myself.

[1] Here's one such variation:

s.define_singleton_method(:loveliness) { "👋 Ben" }
 

yikes... what a mess, the more i work with ruby and search for these kinds of issues, the less thrilled i am with the design of the language

 

I'm actually being shown this error when I try to save an article here in dev.to ... ironic