Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Build an Address Book in Ruby Input and Output Saving The Address Book

Why is it '@contacts' in the 'open' method

Can someone explain why in the 'open' method we are required to use '@contacts' instead of just 'contacts' in order for the 'contacts.yml' to load properly. I thought setting an attr_reader/writer/accessor removed the need for explicitly writing the whole thing out.

Thanks

require "./contact"
require "yaml"

class AddressBook
  attr_reader :contacts

  def initialize
    @contacts = []
    open()
  end

  def open
    if File.exist?("contacts.yml")
      @contacts = YAML.load_file("contacts.yml")
    end  
  end

3 Answers

Vlad Filiucov
Vlad Filiucov
10,665 Points

contacts by it self would be a local variable. it can be accessed only within initialize method. But @contacts is instance variable and it can be accessed outside of the method where it is defined. So if you want to have access to contacts variable from another method you need to make it an instance variable by adding "@" sign in front of it

EDIT

I played around with this some more and looked it up and it appears that I was wrong and the reason you use @ to access the instance variable is due to precedence, because if you just use 'contacts = []' it would create a local variable as local variables take precedence.

END EDIT

The reason @ is needed when assigning to @contacts in this example is because there is only an attr_reader defined for @contacts which means that @contacts can be read from by using contacts but not written to so there are three options.

a) Define attr_writer :contacts (and then you can do 'contacts = []')

attr_reader :contacts
attr_writer :contacts

def initialize
    contacts = []
    ...
  end

b) Define the attr_reader as attr_accessor :contacts (and then you can do 'contacts = []' - the accessor allows you to read/write)

attr_accessor :contacts

def initialize
    contacts = []
    ...
  end

c) when writing to the instance variable explicitly use @contacts (as done in this example)

attr_reader :contacts

  def initialize
    @contacts = []
    ...
  end

Very correct! Thanks for taking time to explain this

Dan Siberry
Dan Siberry
2,964 Points

Does anyone have a answer to this question?

I use attr_accessor for contacts and leave our @ in my code. Why is @ needed for this one function?