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 trialAndrew Goninon
14,925 PointsWhy 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
10,665 Pointscontacts 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
saladspork
19,762 PointsEDIT
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
Andela Restacking
2,608 PointsVery correct! Thanks for taking time to explain this
Dan Siberry
2,964 PointsDoes 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?