In Ruby (and most other programming languages), objects exist in arbitrary memory locations. The dynamic nature of modern computing implies the need for a way to refer to specific objects in memory without having to keep track of their specific memory locations. This is the job of a variable, to point to objects in memory.
In many languages, you must first declare a variable before it can be used. In C (pre-C99), this must be done at the beginning of the function. In more dynamic languages like Perl (with strict enabled), variables may be declared anywhere but must be declared before used. In Ruby, things are a bit different.
You don't declare variables in Ruby, you just start using them. This might seem a bit odd coming from more strict languages, but Ruby is intended to be permissive and expressive without weighing you down with irrelevant details. Ruby maintains tables of known variables and their values for each lexical scope and instance referred to as bindings. Once you start using a variable, Ruby simply creates a new entry in one of these tables. However, that first variable access must be an assignment or Ruby will throw a NameError: undefined local variable or method exception.
The scope of a variable defines where in the program that variable may be accessed. Some have lexical scopes, meaning the areas they may be accessed depend on the physical layout of the program. Others have logical scopes, meaning the areas of the program they may be accessed from are not restricted lexically, but in some other manner. For example, instance variables are only accessible from instance methods, but those instance methods can be declared anywhere (lexically) within the program.
In other languages, like C, lexical scope is everything. There, you really only have global and local variables as well as values obtained via malloc (and pointed to with global or local pointer variables). The Ruby landscape is bit more complex, but still orderly in its own way.
Scope of Variables
One quick thing to note here is that variables do not have a type in Ruby. In languages like C, C++, Java, C#, etc every variable must have a type. This is important because, how these languages are implemented, value types and early binding of function calls are integral to their function. But again, things are a bit different in Ruby.
Variables don't have types in Ruby, values do. Variables in Ruby just point to objects, the type of those objects are irrelevant to the variable itself. The type of object pointed to doesn't even have to stay the same either, it could point to a Fixnum one second and a String the next.
Note that though variables don't have type in Ruby, there are several classifications of variables that define a variable's scope. This is often denoted by prepending a character such as @ (at sign) or $ (dollar sign) to the beginning of the variable. In other languages, such as Perl, this denotes a variable's type. For example, scalar variables begin with a $ (dollar sign) and arrays begin with @ (at sign). In Ruby, any symbols prepended to a variable's name says nothing about the type of object the variable may refer to, only the scope of the variable.
There are several types of variables in Ruby. Though each is used in its own way, they generally follow the same patterns. They're all dynamically typed named storage for objects that are accessible at varying scopes and (for the most part) must be assigned to before read. There are some intricacies at play here, but for the most part the common uses of local and instance variables come with no surprises.
- Local Variables - Typically the most common type of variable. Local variables exist within specific lexical scopes, and go "out of scope" when that scope ends.
- Instance Variables - These exist within the context of an instance. Each instance of a class will have its own specific set of these variables, independent from other instances of the same class.
- Class Variables - These exist at the class level, and are accessible from the class scope (inside the class, but outside of any methods) and within class methods.
- Global Variables - These are rarely used as they break the rules of encapsulation. However, Ruby supports them and they are used in a few places.
- Constants - Constants can be similar to both local and class variables in their scope, and can only be assigned to once (though there are workarounds). They also have a surprising use in how the class hierarchy is implemented.