-
Notifications
You must be signed in to change notification settings - Fork 2
Ruby error: undefined local variable or method
If your error looks like ...
my_program.rb:2:in `display_greeting':
undefined local variable or method `name' for main:Object
(NameError) from my_program.rb:6:in `<main>'
... then ruby needs a variable or method defined before you can use it.
When you type a word into ruby, and it's not a keyword (e.g. if
, else
, def
, class
, etc.), ruby will first try to treat the word as a variable if it was previously defined, and if not, try to call a method using that word.
Double-check your spelling, and remember that variables and methods should be lowercase.
Ruby treats text between single or double-quotes as strings. Did you forget to put the text between quotes and now ruby thinks it's a variable or method?
For example, if I have the following code:
name = sean
Ruby would think that sean is a method or variable. What I really need is quotes around 'sean':
name = 'sean'
Ruby is only aware of local variables in the methods they are defined.
For example, if I have the following code:
def display_greeting
puts "Hello #{name}"
end
name = 'Sean'
display_greeting
Ruby would raise an error as name
does not carry over into the display_greeting
method.
One way to solve this is to pass the name
variable as an argument into the method:
def display_greeting(name)
puts "Hello #{name}"
end
seany = 'Sean'
display_greeting(seany)
Class methods begin with self.
and instance methods do not.
For example, I'd like to display all my contacts nicely in a nicely formatted way, but here, I haven't properly defined display_all
as a class method:
class Contact
@@all = []
attr_accessor :name, :phone
def initialize(name, phone)
@name = name
@phone = phone
@@all << self
end
def display_all
puts 'Contacts'
puts '--------'
@@all.each do |contact|
puts "Name: #{contact.name}"
puts "Phone: #{contact.phone}"
end
end
end
Contact.new('Sean', '416-555-5555')
Contact.new('Sasha', '416-555-4444')
Contact.display_all
To fix this, I have to change display_all
into a class method:
def self.display_all
puts 'Contacts'
puts '--------'
@@all.each do |contact|
puts "Name: #{contact.name}"
puts "Phone: #{contact.phone}"
end
end
This is a living document. If you have anything to add, change or remove, please let us know. Or better yet, as it's a wiki, make the change yourself!