Global Variables
$variable_name Various · Updated March 13, 2026 · Keywords Global variables in Ruby are variables that can be accessed from anywhere in your program. They are denoted by a $ prefix and remain in scope throughout the entire execution of your program, from the moment they are defined until the program terminates.
Characteristics of Global Variables
Unlike local variables which are confined to their lexical scope (the method, class, or block where they’re defined), global variables can be accessed and modified from any location in your code. This makes them powerful but also potentially dangerous if misused.
Automatic Global Variables
Ruby provides several built-in global variables that are automatically available:
# $0 - The name of the current Ruby script being executed
puts $0 # => "my_script.rb" when running ruby my_script.rb
# $$ - The process ID of the current Ruby process
puts $$ # => 12345 (or whatever the PID is)
# $? - The exit status of the last child process
system("ls")
puts $?.success? # => true or false
# $ARGV / @ARGV - Command line arguments
# $LOAD_PATH - Array of directories to search for require
# $DEBUG - True if -d flag was used
# $VERBOSE - Verbosity level
Common Uses
# Storing application-wide configuration
$config = { theme: "dark", language: "en" }
# Sharing state between methods
$request_count = 0
def handle_request
$request_count += 1
puts "Request ##{$request_count}"
end
Best Practices
Avoid When Possible
Global variables make code harder to test and reason about because any part of your program can modify them. Consider these alternatives:
# Instead of global variables, use constants for configuration
class Config
THEME = "dark"
MAX_CONNECTIONS = 100
end
# Or use class variables / class instance variables
class Database
@connection = nil
def self.connection
@connection ||= connect
end
end
When Global Variables Are Acceptable
There are legitimate uses for global variables:
# Debugging flags
$DEBUG_MODE = true
# Global state for gems/libraries
$stdout.sync = true # Ruby built-in global for output sync
# Singleton pattern with globals (limited use cases)
$instance ||= MyClass.new
Reading and Writing
# Assignment
$my_global = "Hello"
# Reading
puts $my_global
# Can be read before assignment (returns nil)
puts $undefined_global # => nil
Caveats
# Global variables are not thread-local by default
$counter = 0
threads = 10.times.map do
Thread.new { 1000.times { $counter += 1 } }
end
threads.each(&:join)
puts $counter # => 10000 (but could vary due to race conditions!)
While global variables can be useful for truly global state like logging configuration or debug flags, prefer passing data explicitly through method arguments or using dependency injection for better, more maintainable code.