The Life‑Changing Magic of Ruby and Rails

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.

Subscribe to Akshay's Blog

Sign up now to get access to the library of members-only issues.
Jamie Larson
Subscribe