This is my attempt to untangle the scope and use of the different variable types in Ruby. Because there’s no topic that can’t be explained through the medium of tenuous Star Wars analogies…
Instance variable = R2D2
R2D2 is loyal to his core. Remember in Episode IV when he would only show the full video of Leia to his true master Obiwan? Total instance variable behaviour right there.
Instance variables begin with a ‘@’, and are normally set up as part of a class initialize function, like so..
So each virtual Ewok we create will have it’s own name and fur density data, and will proudly carry that data around with them, wherever they end up in your program. We can also use those instance variables in any instance methods that we’ve written within the class block, eg.
So now, we’re able to create a new Ewok using:
ewok1 = Ewok.new(“Wicket”, 80)
and we can send Wicket on a spa day using the below:
However, if we want to know an Ewok’s name, we still can’t access this outside of the class block. There is two different approaches to solve this, using a method and using attribute reader, as below:
In fact, they’re not really so different — all the attr_reader function does is create a secret method as on the right. Either way, you can then call ewok1.name anywhere in your program, as long as it knows what ewok1 is. As long as your program can access the class instance you want to work with, it can access any of the instance methods too, even if it doesn’t have visibility of the file where you’ve defined your class. It’s like each instance wraps up all the info about itself and carries it around. You could even pass the Ewok into another method as an argument, and you’d still be able to access it’s data, as below..
Instance variable that is not part of a declared class = Yoda
An instance variable not linked with a class, you say? How can that even be possible? Just try starting a new ruby file and throw in an @variable. Like Yoda, these instance variables are not afraid to live off-grid. However, the class system in Ruby is kind of like the Force — it’s energy surrounds us and helps your code grow. So what you might not realise is that by the very act of creating a filename.rb file, by default anything you write is under the umbrella of the Object class. Like the force this can yeild great power, making instance variables of that class behave like global variables. And like the force this can have a dark side — see the section on global variables later.
Class constant = Stormtrooper fashion sense
Open scene: Derek’s bedroom. We can see that Derek is a stormtrooper, just waking up in the morning. We can hear his internal monologue..
“Oh wow, look at that sunshine. And it’s Friday! Hells yeah, today is gonna be a good day. I’m gonna catch some prisoners, resist their Jedi mind tricks, and have bants with Darth at the Death Star post-work drinks. I’m gonna rock it. The world is going to be my droid. “On fleek” was INVENTED for me. Today is an orange helmet day.”
This never happened. Stormtroopers are hugely uninventive when it comes to their look. We can express this in Ruby as below, using a class constant. Class constants are available anywhere in your program that has visibility of your class, using ‘::’.
Class variable = Leia
This is where it gets very tenuous, I picked Leia as an exemplar for class variables as she’s a classy lady (arf!) and the @@ that precede them look a bit like her hairstyle.
Class variables are those that are tied up to a class but are not tied to individual instances of that class. They can’t be accessed using attr_reader, but can be visible outside the class block using a class method. We can also use a class method if we want to change the value. Class methods always start with self, and are called on the class rather than an instance of it, as below..
Right now if you tried to call .boyfriend on an instance of Leia (instead of on the class itself) ruby gets confused. However, the class variable is available to instance methods or variables. So if we set up a boyfriend method that returns @@boyfriend, then suddenly calling .boyfriend on an instance of Leia will work! You can also set up instance methods to change the value of the class variable too.
Class instance variables = Grown up Leia
OK, here is where it does get a bit confusing. You can also have class level variables that look like instance variables, with just one ‘@’. The reason you know that they are really class level variables is that they are only accessible using class methods, and unlike the ‘@@’ version, they are not available to instance methods. As Leia has grown older, she’s changed her hairstyle, and grown more selective about who she associates with. But she’s still the same classy lady we know and love.
Global variables = the Death Star
The death star, like a global variable, can be seen from the far corners of the universe. They start with a $ and are accessible to any part of your program that has visibility of the file in which they are defined. This means they are very powerful, but this power carries great danger. All it took was some stolen plans, a few overgrown teddy bears and rag-tag rebel force to blast the Death Star into dust. So just think what havoc a few typos or a misguided collaborator could cause to the integrity of your program if global variables are involved. Only to be used by beginners, or the very advanced…
If you like this post, don’t forget to recommend and share it. Check out more great articles at Code Like A Girl.