Ruby classes allow programmers to create all sorts of different kinds of objects. By creating class-specific methods and passing shared variables between them, it's possible to pass a couple arguments to a new instance of a class and do almost anything with them. But to keep track of how those arguments are stored, it's necessary to use something called instance variables.
Until I started working with classes, I had only been exposed to local variables. Local variables have the smallest scope of any variable type in Ruby. Scope describes what parts of a program can access a variable. With a local variable, the scope is very small; the variable only works within the construct where it's defined. Here's an example of how we can define a local variable in a loop, but the variable doesn't exist outside the loop.
The last line of the code will return "undefined local variable or method `x' for main:Object" because we did not define x outside the loop. If we had defined x, the value returned would have nothing to do with the loop's x variable. It's possible to create different local variables with the same name in a prograhttp://i.imgur.com/lp2OnOy.pngm, and have them work independently of one another. Maybe not the best practice in terms of readability and bug-proofing, but possible nonetheless.
There are also global variables, which start with a "$" and can be manipulated in any scope, whether it's a class, loop, block, method, or something else. Working with global variables can be very dangerous because one area of a program may alter a variable and pass it to another area that was counting on that variable starting with a set default value. Things can get dicey pretty quickly there.
When I'm building a class, I'm usually not interested in starting with variables that are globally big or locally small. I want the sweet spot, something that I can work with anywhere in the class (be that in general, in a method, or in a block or loop contained within that method) without being able to affect it when I'm not working within that class. To work with an object like this, I can initialize the class with instance variables. Allow me to illustrate by making a class whose instances represent different sandwiches:
This looks a little redundant at first, but what just happened is absolutely crucial to Sandwich working as a functional class later on. In the initialize method, we define the arguments that the class can take. We want each Sandwich to have meat, cheese and bread values stored. But what good is storing them if we can't use them? By using the @ symbol in front of a variable, we create an instance variable that can be accessed from anywhere within a given sandwich. (They're called instance variables because each given sandwich is an instance of the Sandwich class.)
Since @meat, @cheese, and @bread can be accessed from anywhere within Sandwich, we can now create some more methods that use our instance variables:
Now we can see the magic of instance variables in action. Notice how the instance variables can show up in any method to be accessed and modified. This allows us to take the initial arguments, modify them with specific instructions, and return the results:
We can do all of this without having to redefine @meat, @cheese, or @bread within each method. We did that at initialization and we don't need to do it again. It's that simple! One last warning, though: It's possible to set instance variables outside of a class, but they have nothing to do with the instance variables within the class. They don't speak to each other. Check out an example:
So it's still important to keep track of your variable usage and name things appropriately. Whatever the scope of the variable you use, there is a way to screw something up. To avoid this, comment your code as you go along, and don't use the wrong type of variable for a situation. (I had no business creating @bread outside of a class just now!) By building classes with instance variables, you can unleash all their power and create some truly functional code. Take a stab at it for yourself. Good luck, and happy coding!