Can You Spot the Error?
Do you see the error in this simple Ruby snippet?
class Person
attr_accessor :name
def assign_name
name = 'akshay'
end
def greet
puts 'my name is ' + name
end
end
Let’s assign name to a Person
object to see the problem in action.
ak = Person.new
ak.assign_name
=> "akshay"
So far, so good. Now try to access the name with the greet
method.
ak.greet
# Error: no implicit conversion of nil into String (TypeError)
How’s that possible? Didn’t we just assign the value to name
? Ruby even confirmed by returning the value from the assignment? Why did the name
variable not retain its value?
The answer is in the way Ruby handles assignments inside objects. Let’s review the method again.
def assign_name
name = 'akshay'
end
In the following code, name
is a local variable, instead of the setter method created by attr_accessor
. To access the setter method, we need to use self
, like this:
def assign_name
self.name = 'akshay'
end
Using self
ensures that Ruby sets the current User
’s name method, instead of creating a local variable.
Here’s the complete working example:
class Person
attr_accessor :name
def assign_name
self.name = 'akshay'
end
def greet
puts 'my name is ' + name # or self.name
end
end
> ak = Person.new
=> #<Person:0x0000000114bcb190>
> ak.assign_name
=> "akshay"
irb(main):059:0> ak.greet
my name is akshay
=> nil
Hope this was useful, and you learned something new.