Global Variables

$variable_name
Returns: Various · Updated March 13, 2026 · Keywords
variables scope state global

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.

See Also