Global Variables in Ruby

hand reaching out of a computer to grab ruby
erhui1979 / Getty Images

Global Variables are variables that may be accessed from anywhere in the program regardless of scope. They're denoted by beginning with a $ (dollar sign) character. However, the use of global variables is often considered "un-Ruby," and you will rarely see them.

Defining Global Variables

Global variables are defined and used like any other variable. To define them, simply assign a value to them and begin using them. But, as their name suggests, assigning to global variables from any point in the program has global implications. The following program demonstrates this. The method will modify a global variable, and that will affect how the second method runs.


$speed = 10
def accelerate
$speed = 100
end
def pass_speed_trap
if $speed > 65
# Give the program a speeding ticket
end
end
accelerate
pass_speed_trap

Unpopular

So why is this "un-Ruby" and why don't you see global variables very often? Put simply, it breaks encapsulation. If any one class or method can modify the state of the global variables at will with no interface layer, any other classes or methods that rely on that global variable may behave in an unexpected and undesirable manner. Further, such interactions can be very difficult to debug. What modified that global variable and when? You'll be looking through quite a lot of code to find what did it, and that could have been avoided by not breaking the rules of encapsulation.

But that's not to say that global variables are never used in Ruby. There are a number of special global variables with single-character names (a-la Perl) that can be used throughout your program. They represent the state of the program itself, and do things like modify the record and field separators for all gets methods.

Global Variables

  • $0 - This variable, denoted by $0 (that's a zero), holds the name of the top-level script being executed. In other words, the script file that was run from the command line, not the script file that holds the currently executing code. So, if script1.rb was run from the command line, it would hold script1.rb. If this script requires script2.rb, $0 in that script file would also be script1.rb. The name $0 mirrors the naming convention used in UNIX shell scripting for the same purpose.
  • $* - The command-line arguments in an array denoted by $* (dollar sign and asterisk). For example, if you were to run ./script.rb arg1 arg2, then $* would be equivalent to %w{ arg1 arg2 }. This is equivalent to the special ARGV array and has a less descriptive name, so it is rarely used.
  • $$ - The interpreter's process ID, denoted by $$ (two dollar signs). Knowing one's own process ID is often useful in daemon programs (which run in the background, unattached from any terminal) or system services. However, this gets a bit more complicated when threads are involved, so be wary of using it blindly.
  • $/ and $\ - These are the input and output record separators. When you read objects using gets and print them using puts, it uses these to know when a complete "record" has been read, or what to print between multiple records. By default, these should be the newline character. But since these affect the behavior of all IO objects, they're rarely used, if at all. You may see them in smaller scripts where breaking the encapsulation rules is not an issue.
  • $? - The exit status of the last child process executed. Of all the variables listed here, this is probably the most useful. The reason for this is simple: you can't get the exit status of child processes by their return value from the system method, only true or false. If you must know the actual return value of the child process, you need to use this special global variable. Again, the name of this variable is taken from the UNIX shells.
  • $_ - The last string read by gets. This variable may be a point of confusion for those coming to Ruby from Perl. In Perl, the $_ variable means something similar, but totally different. In Perl, $_ holds the value of the last statement and in Ruby it holds the string returned by the previous gets invocation. Their usage is similar, but what they really hold is very different. You don't often see this variable either (come to think of it, you rarely see any of these variables), but you may see them in very short Ruby programs that process text.

In short, you'll rarely see global variables. They're often bad form (and "un-Ruby") and only really useful in very small scripts, where the full implication of their use can be fully appreciated. There are a few special global variables that can be used, but for the most part, they aren't used. You don't really need to know all that much about global variables to understand most Ruby programs, but you should at least know that they're there.

Format
mla apa chicago
Your Citation
Morin, Michael. "Global Variables in Ruby." ThoughtCo, Jul. 31, 2021, thoughtco.com/global-variables-2908384. Morin, Michael. (2021, July 31). Global Variables in Ruby. Retrieved from https://www.thoughtco.com/global-variables-2908384 Morin, Michael. "Global Variables in Ruby." ThoughtCo. https://www.thoughtco.com/global-variables-2908384 (accessed March 28, 2024).