DEV Community

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

NoMethodError: undefined method loveliness for nil:NilClass
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 ❤️

Discussion (6)

pic
Editor guide
Collapse
marckohlbrugge profile image
Marc Köhlbrugge • Edited

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.

Collapse
bravemaster619 profile image
bravemaster619 • Edited

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

Collapse
itsjzt profile image
Saurabh Sharma

Undefined is not a function

Collapse
citizen428 profile image
Michael Kohl • Edited

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" }
Collapse
worc profile image
worc

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

Collapse
samfieldscc profile image
Sam Fields

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