HENRY'S BLOG

Classes

Instance Variables

í
In this blog post I will talk about the use of instance variables. To understand what an instance variable is, and how to use it we’ll have a look at an example.

Let's say we have a class Car.
  1. class Car
  2. end

Also, we have a method that returns the color of the car. This color will be returned as a so called instance variable.
  1. class Car
  2.   def what_color
  3.     @color # simply returning an instance variable.
  4.   end
  5. end

The @ indicates the instance variable here.
See what happens, if we are calling the what_color method in order to get the color of the car.
  1. car = Car.new
  2. car.what_color # => nil

First, we create an instance car of the Car class. Second, we call the what_color method. But it returns nil! Of course it does, because we never defined what color the car instance should have.

Let’s try to give the car a color. How about:
  1. car.color = "Black" # => no method error
?

Aha, we can read the color („nil“ in this case), but that doesn't mean we can assign a new color to the car.

For this, we need a „writer“-method in addition to our „reader“-method (what_color):
  1. class Car
  2.   def what_color
  3.     @color
  4.   end

  5.   def give_color=(str)
  6.     @color = str
  7.   end
  8. end

  9. car = Car.new
  10. car.give_color = „Black"
  11. car.what_color # => „Black"

Awesome. Now we can write and read instance variable @color using reader (here what_color) and writer (here give_color) methods.
This is done so frequently, why waste time writing these methods every time? We can do it easier.
  1. class Car
  2.   attr_reader :color
  3.   attr_writer :color
  4. end

This does exactly the same as the class above. It turns out that Ruby already has predefined reader and writer methods called attr_reader and attr_writer, that we can use instead of what color and give_color. Internally they do the same as we did some lines above: They create one reader method that returns @color and a writer method that assigns a string („Black“ if we want to) to the @color instance variable, except that we can’t see this. It could be any other type of object instead of „String“, of course.

If you know that you need read and write access to to instance variable (like in our example), you can cut corners even more:
  1. class Car
  2.   attr_accessor :color
  3. end

This combines both the attr_reader and the attr_writer methods. If you make use of these three attr_x methods, you have access to the instance variable in any other method, like this:
  1. class Car
  2.   attr_accessor :color

  3.   def say_something
  4.     „You wanna know my color? Ok, it’s #{@color}!“
  5.   end
  6. end

  7. car = Car.new
  8. car.color = "Black"
  9. car.say_something # => "You wanna know my color? Ok, it’s Black!“

It’s important to understand this concept thoroughly, because it’s possible to generate a lot of errors if you give access to instance variables from outside, although they were meant to only function inside of its class. That way, someone who uses your code could accidentally overwrite variables.
Using attr_reader/writer/accessor properly prevents you from making those mistakes.