If you want to learn about Ruby instance variables, how they work & why they’re useful.
You’re in the right place!
First question…
What’s an instance variable?
In the Ruby programming language, an instance variable is a type of variable which starts with an @
symbol.
Example:
@fruit
An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data.
We say that objects can:
- Do things
- Know things
Methods make things happen, they DO things.
Instance variables store data, they KNOW things.
Example:
If you have a Fruit
class, you may want to know what kind of fruit it’s, what color, weight, etc.
All of these attributes become instance variables.
Like @color
, @type
, @weight
.
Next:
Let’s see code examples.
How to Define & Use Ruby Instance Variables
You define instance variables inside classes.
Example:
Let’s say we have a CoffeeMachine
class.
A coffee machine needs water, so you may want to know how much water is available.
We can do this:
class CoffeeMachine def initialize @water = 100 end end
This @water
is our instance variable.
We assign 100
to @water
as the initial value.
Now:
If we have a make_coffee
method, we can reduce the amount of water left in the tank.
class CoffeeMachine def initialize @water = 100 end def make_coffee @water -= 10 end end
Notice that every CoffeeMachine
object you create (with new
) will have its own private value for @water
.
Makes sense, right?
Because if you have 10 actual coffee machines, each is going to have their own water levels.
That’s why we use instance variables!
How to Access Instance Variables
Instance variables wouldn’t be very useful if you couldn’t read their current value.
You can read an instance variable value with the @
syntax.
Like this:
class CoffeeMachine def initialize @water = 50 end def print_water_level puts "Water Level: #{@water}" end end machine = CoffeeMachine.new machine.print_water_level # Water Level: 50
The print_water_level
method uses @water
to print its value.
Using Attribute Accessors
You may notice that you can’t access instance variables from outside the class.
That’s by design!
It’s what we call “Encapsulation”, an object’s data is protected from the outside world, like other Ruby objects.
Here’s what I mean:
machine = CoffeeMachine.new machine.water # NoMethodError: undefined method `water' for #<CoffeeMachine:0x2d0a530> machine.@water # SyntaxError: unexpected tIVAR, expecting '('
In some cases, you may want to allow this.
You can open a window into the object’s data so it becomes available from outside.
One way to do that:
class CoffeeMachine def initialize @water = 100 end def water @water end end machine = CoffeeMachine.new machine.water # 100
Nothing special here.
We’re returning the value from inside, where we have access to it.
Another option is to use an attribute reader.
Example:
class CoffeeMachine attr_reader :water def initialize @water = 100 end end machine = CoffeeMachine.new machine.water # 100
Same thing as before.
Only difference is that Ruby will do the hard work for you & create that water
method.
Things You Should Know
A few things to remember about instance variables so you don’t get into trouble.
Take notes:
- An undefined instance variable always returns
nil
- Instance variables don’t have to be created in the
initialize
method, but that’s how you give them an initial value - There are advanced ways to access instance variables, like
instance_variable_get
, but you should avoid these
Btw, you can get a list of instance variables.
Like this:
machine.instance_variables # [:@water]
You may find that helpful 🙂
One more thing:
In Rails, instance variables (like @books
), are used to share data between your controller & views.
But you can still use them normally, for your own classes.
Summary
You have learned about Ruby instance variables! A kind of variable that starts with the @
symbol & it’s used inside classes to give them a place to store data.
Don’t forget to practice now, play with the code examples & come up with your own.
Thanks for reading.
One of the advantages of attr_reader and attr_accessor is that in the event of a typo you get a no method error instead of the expression return nil.
Hi Richard, thanks for your comment 🙂