attr_reader, attr_writer, attr_accessor, and initialize

I just wanted to quickly go over the differences between these, because I’d been confused when I first learned them.

Classes in ruby are defined by

class Person
end

Now, when we create an instance of person…

new_person = Person.new

attr_writer

…we might want to give this new person a name.

new_person = Person.new
new_person.name = "Hyung Cho"

However, because we don’t have a writer method to our class, this will give us the following error `<main>': undefined method `name=' for #<Person:0x0000000101ab20> (NoMethodError)

We can create a writer method in two different ways in Ruby. The first is to use attr_writer:

class Person
  attr_writer :name
end

Because writer and reader methods are so commonly used, Ruby has a built in ‘magic’ function that creates them. To write multiple writers or readers, we can separate them with commas.

The second is to define it this way:

class Person
  def name=(name)
    @name = name
  end
end

These methods are identical, and taking a closer look at the second method might give us a better understanding of what our writer method is actually doing. We’re creating a method name= that takes one argument name and setting it to our instance variable @name. So now, when we try setting our name variable to our name, it doesn’t give us an error.

class Person
  attr_writer :name
end

new_person = Person.new
new_person.name = "Hyung Cho"

Remember, new_person.name = "Hyung Cho" is the same thing as new_person.name=("Hyung Cho"). If you take a look at it you’ll see that we’re just calling the name= method!

attr_reader

Now, let’s say that we want to find out the name of our new_person. The obvious way is to try puts new_person.name. However, that won’t work.

When you throw Ruby puts new_person.name, what you’re telling it is to print whatever the method name returns. At this point however, we don’t have the method name defined. This is called a reader method. Whereas the first writer method has us assigning an instance variable through a writer method, our reader method has us calling another method so we can read that instance variable. Once again, we can accomplish this in two ways:

class Person
  attr_writer :name
  attr_reader :name
end

and the other way,

class Person
  def name=(name)
    @name = name
  end

  def name
    @name
  end
end

So now,

class Person
  attr_writer :name
  attr_reader :name
end

new_person = Person.new
new_person.name = "Hyung Cho"

puts new_person.name

will return

>> Hyung Cho

attr_accessor

With both the reader and writer methods understood, we can combine them into a simpler attr_accessor which creates both.

class Person
  attr_reader :name
  attr_writer :name
end

is the same thing as

class Person
  attr_accessor :name
end

Simple, right?!

Initialize

The initialize method is different than the writer and reader methods even though it may seem similar. Think of initialize methods like this: when you call a method that takes in an argument, let’s say for example

def add_two_numbers(num1, num2)
  num1 + num2
end

puts add_two_numbers(1, 2)

>> 3

num1 and num2 get initialized locally. Similarly, setting initialized variables just tells ruby that when an instance of this class gets created, some specific variables will be created. Here’s an example:

class Person
  attr_reader :name
  
  def initialize(name)
    @name = name
  end
end

new_person = Person.new("Hyung Cho")
puts new_person.name

>> Hyung Cho

If you now try to create an instance of the Person class without throwing it an argument like so

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

new_person = Person.new

it will give you an error `initialize': wrong number of arguments (0 for 1) (ArgumentError)

Don’t be mistaken, an initialized variable does not always need to be thrown as an argument when the object is created. Your initialize method can look something like this:

class Person
  def initialize(name)
    @name = name
    @school = "Crescenta Valley High School"
  end
end

We will never pass in a school argument in the creation of a Person object, but the moment an instance of Person is created, it will automatically set the instance variable @school to "Crescenta Valley High School

There you have it! First time blogging about a technical subject, so any feedback would be appreciated! I tried to explain it in the simplest way possible for beginners to understand.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s