Cross-posted from the official Kickstart Coding blog
The Errors
Here are three code snippets that produce three very similar error messages in three different languages:
In Python
The Code
person.register()
The Error
AttributeError: 'NoneType' object has no attribute 'register'
In JavaScript
The Code
person.register()
The Error
Uncaught TypeError: Cannot read property 'register' of undefined
In Ruby
The Code
person.register()
The Error
NoMethodError: undefined method 'register' for nil:NilClass
Okay, so…?
These errors all happen for the same reason. But it’s not the reason most newbie programmers think. The error messages all talk about register
not existing, so programmers naturally assume that the problem has to do primarily with their register
method not being defined. It sounds like register
doesn’t exist, so they naturally look to make sure they’ve created a register
method in their code.
They might imagine that the error is happening because their Person
class looks something like this (using JavaScript in this example):
class Person {
// Oops, no register method!
}
But when they go to check their code, that’s usually not the problem. The Person
class is usually fine and the register
method is usually present and accounted for.
class Person {
register() {
console.log("I really do exist! Honest!")
}
}
If you find yourself in this situation, it’s more likely that if you zoom out from person.register()
, you’ll find some code that is supposed to put a value into the person
variable, and that code is the true culprit. Let’s say, for example, you’ve got a function that searches for a person by their e-mail address and then returns that person if it can find them. The code might look something like this:
person = getPersonByEmail("some_email@some_website.com")
person.register()
In this example, the most likely real problem would be that getPersonByEmail
is not finding a person. It has nothing whatsoever to do with a missing register
method, in spite of what the error message would lead you to believe.
There are two pieces of information in each of these error messages. They tell you explicitly that register
doesn’t exist. But they also tell you implicitly that person
doesn’t exist.
‘NoneType’ object has no attribute ‘register’
Cannot read property ‘register’ of undefined
NoMethodError: undefined method ‘register’ for nil:NilClass
NoneType
, undefined
, and NilClass
are the ways these three languages represent something that doesn’t exist. Nine times out of ten, when you see this error message, your implementation of the register
method is fine. It’s your person
variable that’s the problem. It should be an object representing a person, but instead it’s NoneType
, undefined
, NilClass
, in other words, nothing.
There’s probably a perfectly fine register
method written for the Person
class. But there’s no register
method written for a NoneType
. There’s no register
method written for undefined
. And there’s no register method written on an instance of NilClass
.
If you see this kind of error, then the most likely problem with your code is that person
isn’t getting set to the right thing, like in our example where getPersonByEmail
can’t find a person with the e-mail you gave it. If getPersonByEmail
can’t find a match, person
doesn’t get set to anything at all. And because it isn’t set to anything, when you try to call register
on it, you get a “register
doesn’t exist” message because register
exists for Person
objects, not for “nothing” objects.
Because of the way these error messages emphasize register
not existing, it takes a while for newbies to learn to check on what’s going on with person
in the rest of their code when this happens instead of automatically zooming in on register
.