FAQ: Object-Oriented Programming II - attr_reader, attr_writer

This community-built FAQ covers the “attr_reader, attr_writer” exercise from the lesson “Object-Oriented Programming II”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn Ruby

FAQs on the exercise attr_reader, attr_writer

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

In the example code it shows attr_reader and attr_writer above the initialize method

If code is read from top to bottom I wonder that initialize must come first to establish the instance variable before it can be called by attr_reader or attr-writer?

Also I think I am struggling with the attr_accessor -

the main idea is just to shortcut writing out a method? It still has to be defined inside the class though correct?

… or eliminating the need for one (or many).

Since the attr_... references symbols, not variables, they can be written above any other code in the class. Ruby will look up the associated instance variable and create the necessary binding in real time.

To demonstrate, and assuming you have completed the lesson, comment the three lines you have for attr_... and add in this line,

attr_accessor :name, :job

Now try this code in the run segment…

joe = Person.new('Joe','Programmer')
puts "Name: #{joe.name}\nJob: #{joe.job}"
joe.name = "Joseph"
joe.job = "Writer"
puts "Name: #{joe.name}\nJob: #{joe.job}"

You should see this,

Name: Joe
Job: Programmer
Name: Joseph
Job: Writer

Notice how attr_accessor gives read/write permissions to both instance variables?

There are three scenarios, as it were.

attr_reader :symbol[, :symbol[, ...]]
attr_writer :symbol[, :symbol[, ...]]
attr_accessor :symbol[, :symbol[, ...]]

It would be strange to have a write accessor but not be able to read what was written (without a method), so that brings us down to two scenarios…

attr_reader :symbol[, :symbol[, ...]]      # Read Only
attr_accessor :symbol[, :symbol[, ...]]    # Read and Write
1 Like

I’m having difficulty understanding the explanation in this lesson.

First, it states, “We saw in the lesson on classes that Ruby needs methods in order to access attributes.” However, the embedded link does not work and I can’t find the lesson on classes when I go through the list of Ruby lessons. Can anyone provide the correct link?

Next, can someone please explain what an attribute is?

Anything prefixed with @ is an instance attribute, and anything prefixed with @@ is a class attribute.

Ah, Ok Yes. But what actually is an attribute? Is it the same as a variable?

Reviewing the prior exercises, up to now the exercises have been describing instance variables and class variables. So now we have instance and class attributes hence my question, as I don’t recall seeing an explanation of attributes and the link provided (presumably referring back to the relevant lesson) does not work.

The term ‘attribute’ implies, attribute => value pair. Other than that the two terms are very nearly synonymous.

Ruby has a docs site which should become your goto for anything fundamental.

Thanks for the help. Unfortunately I don’t quite understand what attribute => value pair means, or how it relates to a variable. I was hoping this course would teach the fundamentals of Ruby! Do you know the link for the Ruby docs site?
thanks

Google SERP
https://www.google.com/search?client=firefox-b-d&q=Ruby+docs

Thanks for the link. Seems like there are several resources out there but unfortunately, when I searched for attribute I got about 100 results and after reviewing several of the results I’m not really finding an explanation of what an attribute is. Strange that the exercises don’t mention it up to this point so I’m thinking there’s an error in the curriculum.

In pseudo terms, an object is a data structure comprised of zero or more key => value pairs. This is known as an associative array in some languages, such as PHP.

In JavaScript an object literal looks like this…

object_name = {
    prop1: 'value1',
    prop2: 'value2',
    // ...
}

We refer to them as properties.

Properties are either accessible values, or callable objects known as methods.

Ruby has constraints that prevent direct access of attributes, what we could refer to as variables, from outside of the class definition, hence the need to for accessor methods.

Thanks. But I think I’m more confused.

So if I’m understanding correctly, an *attribute => value pair is the same as a key => value pair is the same as a property which could be a method or a variable, and a method itself is an object (so a method also has key => value pairs)? What is an accessible value vs a property or attribute?

I’m confused because it seems like there are so many names for what seems like the same thing, or maybe I’m not understanding that they are different things.

class Person
  def initialize(name, job)
    @name = name
    @job = job
  end
end

Once we create an instance, how are we to access the attributes? (Remember, they are the ones with the @ prefix.)

Notice they have a name/value relation? The pair is together what makes up an attribute.

Back to the question of accessing. How will we poll the values ensconced within our instance?

# create a `billy` instance
billy = Person.new('Billy Jones', 'Marketer')

The simple fact is we don’t, not without instance methods to support accessing the attributes.

class Person
  def initialize(name, job)
    # attributes
    @name = name
    @job = job
  end
  # accesor methods
  def name
    @name
  end
  def job
    @job
  end
  def name=(value)
    @name = value
  end
  def job=(value)
    @job = value
  end
end

And now an instance…

joe = Person.new('Joe','Programmer')       # create instance
puts "Name: #{joe.name}\nJob: #{joe.job}"  # access READ
joe.name = "Joseph"                        # access WRITE
joe.job = "Writer"                         # access WRITE
puts "Name: #{joe.name}\nJob: #{joe.job}"

Output in the console…

Name: Joe
Job: Programmer
Name: Joseph
Job: Writer

The import of this lesson if I’m not mistaken is how Ruby has built in methods that can abstract away the verbose definitions, and accomplish the same thing.

class Person
  attr_accessor :name, :job
  def initialize(name, job)
    @name = name
    @job = job
  end
end

One line of code replaces twelve. Repeat the instance and see…

Name: Joe
Job: Programmer
Name: Joseph
Job: Writer

There are cases where we do not wish to grant write permission, in which case we would use, attr_reader.

In any case one would hope we are at least burning away some of the fog. Ruby is so simple and intuitive on the surface, but it soon overwhelms unless the learner is devoted and dedicated.

Thanks for taking the time to create such a detailed reply. Unfortunately I’m still very confused and I really don’t understand this exercise. I was able to follow the instructions and complete the challenge in the exercise just by duplicating the code in the example. However, I don’t understand the purpose of changing the code in this way, or what the result of this would be. I’m still unclear on how an attribute differs from a variable or a property or a key/value pair. I also don’t understand what it means to access the attributes. I don’t understand what an instance method is, and I’m still unclear what an instance variable is. I thought that a method was a Ruby function, but I’m not clear on that either at this point. Right now, with every further explanation, I’m becoming more lost and confused, so I think I’m just going to move on to the next exercise.

We discussed how most of those terms are synonymous or similar. They all hinge on a name, and an associated value. The name could be referred to as an object key, and the value is associated to that key.

key => value   # key/value pair

variable = value    # variable is a key on the scoped object.

Ruby would rather we make assignments as methods. A method is a function of the global object, or a function of a class. Technically, Ruby doesn’t have functions, only methods.

https://stackoverflow.com/questions/1194585/what-is-the-difference-between-methods-and-attributes-in-ruby

def mol
  42
end

puts mol
# 42

def tmol
  'The meaning of life is, #{mol}.'
end

puts tmol
# The meaning of life is, 42.