Ruby Build an Address Book in Ruby Class Design Phone Number Class

Can someone explain why we don't need the @ symbol for instance variables in our code outside of the initialize method?

I know we use the @ symbol to indicate that a variable is an instance variable. We do this inside of our initialize method.

I'm following along the videos however and noticed that Jason was able to do this:

class Contact
  attr_writer :first_name, :middle_name, :last_name
  attr_reader :phone_numbers

  def initialize
      @phone_numbers = []

  def last_first
      last_first = last_name
      last_first += ", "
      last_first += first_name
      if !@middle_name.nil?
        last_first += " "
        last_first += middle_name.slice(0,1)
        last_first += "."

  def print_phone_numbers
      puts "Phone Numbers"
      phone_numbers.each {|phone_number| puts phone_number}

Our initialize method has instance variable @phone_numbers, which is an empty array. In our print_phone_numbers method, he loops through the array but phone_numbers doesn't have the @ symbol in front.

My question: Why is that the case? Is the @ symbol just not needed after the initialize method? From my understanding an instance variable can be used throughout the entire class it belongs to, so is that why we don't need the @ symbol?

This is confusing to me because in our last_first method, he does use the @ symbol when referring to @middle_name in the if statement. @middle_name was not in the initialize method.. is that why the @ symbol is needed in this case?

I might be digging into instance variables a bit much. Hope someone can help clarify!


3,101 Points

Hello Benjamin!

We don't have to use an "@" symbol because we define our attribute accessors (getters and setters) on lines 2 and 3 (after the "class" keyword). It's a shorthand for defining each getter and setter manually like this:

Getters (attribute readers):

def last_name=

def first_name

Setters (attribute writers):

def last_name=(new_lname)
    @last_name = new_lname

def first_name=(new_fname)
    @first_name = new_fname

So the way they were written in the video is just a convenience way (and the one you will see very often in the wild) of writing methods that you use to get and set your class states.

1 Answer

Oliver Duncan
Oliver Duncan
16,640 Points

@kmineskiy is right. Assuming that you meant to have an attr_reader on @first_name and @last_name instead of attr_writer, there's a huge difference between @first_name and first_name. The first is the instance variable that you have defined in your class. The second is the getter method, written automatically by attr_reader :first_name, that returns that variable. When you use first_name without an @, you're calling a method that returns that instance variable. By contrast, @middle_name doesn't have an attr_reader, and therefore no getter method. If you try to call the method middle_name, you will get an NoMethod exception.

Thanks Oliver Duncan & kminevskiy ! He briefly explains this as well in the next video or two :P