Skip to content

Ruby Variables

Variables are named memory locations that hold data used by a program. Understanding how Ruby handles variables, constants, and different data literals is fundamental to writing effective Ruby code.

Ruby supports several types of variables, each with a specific scope and purpose. This chapter will delve into these types, building upon any prior brief introductions.

Global variables begin with a dollar sign ($). For example, $admin_user. If a global variable is used before it’s initialized, it has the value nil. Using an uninitialized global variable will produce a warning if Ruby is run with the -w or -W (verbose) flag.

Assigning a value to a global variable makes it accessible from anywhere in your program. However, it is generally discouraged to use global variables extensively. They can make programs difficult to understand, debug, and maintain because they can be modified from anywhere, leading to unexpected side effects. Prefer passing data through method arguments or using other scoping mechanisms.

Here’s an example demonstrating the use of a global variable:

#!/usr/bin/env ruby
$global_variable = 10
class Class1
def print_global
puts "Global variable in Class1 is #{$global_variable}"
end
end
class Class2
def print_global
puts "Global variable in Class2 is #{$global_variable}"
end
end
class1_obj = Class1.new
class1_obj.print_global
class2_obj = Class2.new
class2_obj.print_global

In this example, $global_variable is accessible within both Class1 and Class2. This code will output:

Global variable in Class1 is 10
Global variable in Class2 is 10

Note on String Interpolation: In Ruby, to embed the value of a variable or an expression within a double-quoted string, you use #{expression}. For example, "Value: #{my_variable}".

Instance variables begin with an at sign (@), for example, @user_name. They belong to a specific instance (object) of a class. Each object has its own set of instance variables. Uninitialized instance variables have the value nil and will produce warnings with the -w option if accessed before assignment.

Here’s an example of instance variables:

#!/usr/bin/env ruby
class Customer
def initialize(id, name, address)
@cust_id = id
@cust_name = name
@cust_address = address
end
def display_details
puts "Customer ID: #{@cust_id}"
puts "Customer Name: #{@cust_name}"
puts "Customer Address: #{@cust_address}"
end
end
# Create Objects
cust1 = Customer.new("1", "John Doe", "123 Main St, Anytown")
cust2 = Customer.new("2", "Jane Smith", "456 Oak Ave, Otherville")
# Call Methods
cust1.display_details
cust2.display_details

Here, @cust_id, @cust_name, and @cust_address are instance variables. Each Customer object will have its own values for these variables. The output will be:

Customer ID: 1
Customer Name: John Doe
Customer Address: 123 Main St, Anytown
Customer ID: 2
Customer Name: Jane Smith
Customer Address: 456 Oak Ave, Otherville

Class variables begin with two at signs (@@), for example, @@total_users. They are shared among all instances of a class, and also by the class itself and its subclasses. Class variables must be initialized before they are used in method definitions, otherwise, an error will occur. Overriding a class variable in a subclass can lead to warnings if the -w option is enabled.

Example of a class variable:

#!/usr/bin/env ruby
class Customer
@@no_of_customers = 0 # Initialize class variable
def initialize(id, name, address)
@cust_id = id
@cust_name = name
@cust_address = address
@@no_of_customers += 1
end
def display_details
puts "Customer ID: #{@cust_id}"
puts "Customer Name: #{@cust_name}"
puts "Customer Address: #{@cust_address}"
end
def self.total_no_of_customers # Class method to access class variable
puts "Total number of customers: #{@@no_of_customers}"
end
end
# Create Objects
cust1 = Customer.new("1", "John Doe", "123 Main St, Anytown")
cust2 = Customer.new("2", "Jane Smith", "456 Oak Ave, Otherville")
# Call class method
Customer.total_no_of_customers
cust3 = Customer.new("3", "Robert Brown", "789 Pine Ln, Sometown")
Customer.total_no_of_customers

Here, @@no_of_customers is a class variable. It tracks the total number of Customer objects created. The output will be:

Total number of customers: 2
Total number of customers: 3

Local variables begin with a lowercase letter or an underscore (_). For example, count or _temp. The scope of a local variable is limited to the block, method, class, or module definition where it is declared. They are not available outside their defined scope.

If you reference an uninitialized local variable, Ruby interprets it as a call to a method with that name and no arguments. If no such method exists, a NameError will be raised.

Assigning a value to a name that follows local variable naming conventions declares it as a local variable. It exists until the end of its current scope. In the Customer class examples above, id, name, and address (parameters to initialize) are local variables within that method.

Constants begin with an uppercase letter. For example, Version or MAX_USERS. Constants defined within a class or module are accessible from within that class or module. Constants defined outside any class or module are accessible globally.

Constants cannot be defined within methods. Attempting to reference an uninitialized constant results in a NameError. While Ruby allows you to reassign a value to an already initialized constant, it will produce a warning, as constants are intended to hold values that do not change.

#!/usr/bin/env ruby
class Example
VAR1 = 100
VAR2 = 200
def show
puts "Value of first Constant is #{VAR1}"
puts "Value of second Constant is #{VAR2}"
end
end
# Create Object
object = Example.new
object.show
# Accessing constant from outside the class (if defined at top level or using scope resolution)
# puts Example::VAR1 # This is how you'd access it if needed externally

Here, VAR1 and VAR2 are constants. The output will be:

Value of first Constant is 100
Value of second Constant is 200

Pseudo-variables are special keywords that behave like variables but whose values cannot be assigned by your code. They have predefined meanings.

  • self: The receiver object of the current method. In a class definition but outside an instance method, self refers to the class itself.
  • true: Represents boolean truth.
  • false: Represents boolean falsehood.
  • nil: Represents ‘nothing’ or an undefined value. It’s an object, the single instance of NilClass.
  • __FILE__: The path to the current source file.
  • __LINE__: The current line number in the source file.
  • __ENCODING__: The script encoding of the current file.

Literals are fixed values directly represented in source code. Ruby’s rules for literals are generally intuitive.

Ruby supports integer numbers. Since Ruby 2.4, Fixnum and Bignum have been unified into a single Integer class, which automatically handles numbers of any size, limited only by available memory. You don’t need to worry about the distinction between small and large integers anymore.

Integers can be written with an optional leading sign. You can use base indicators: 0 for octal (e.g., 0o377 or 0377), 0x for hexadecimal (e.g., 0xff), and 0b for binary (e.g., 0b1011). Underscore characters (_) can be used within numbers for readability and are ignored (e.g., 1_234_567).

A question mark preceding a character yields its ASCII/encoding integer value (e.g., ?a is the integer value for ‘a’, ?\n for newline).

Examples:

123 # Decimal
1_234 # Decimal with underscore for readability
-500 # Negative decimal
0o377 # Octal (or 0377)
0xff # Hexadecimal
0b1011 # Binary
?a # Integer code for character 'a'
?\n # Integer code for newline (0x0a)
12345678901234567890 # A large integer

Ruby supports floating-point numbers (numbers with a decimal point). These are objects of the Float class.

Examples:

123.4 # Standard floating point
1.0e6 # Scientific notation (1.0 * 10^6)
4E20 # Scientific notation (dot not required if 'E' is present)
4e+20 # Sign for exponent is optional for positive

Ruby strings are sequences of bytes, typically representing characters, and are objects of the String class. Ruby supports various ways to create strings:

  • Single-quoted strings ('...'): Perform minimal interpretation. Backslash notation only supports \' (for a literal single quote) and \\ (for a literal backslash). Interpolation (#{...}) is not performed.
  • Double-quoted strings ("..."): Support a wide range of backslash escape sequences (see below) and expression interpolation using #{expression}.
  • %q{...} or %Q{...} (and other delimiters): General-purpose string quoting. %q behaves like single quotes, and %Q behaves like double quotes. You can use various delimiter pairs like (), [], <>, or even non-paired characters like !...! or |...|.

Example with single and double quotes:

#!/usr/bin/env ruby
puts 'escape using \\ backslash'
puts 'That\'s right'
name = "Ruby"
puts "Hello, #{name}!\nThis is a new line."

This will produce:

escape using \ backslash
That's right
Hello, Ruby!
This is a new line.

String interpolation example:

#!/usr/bin/env ruby
seconds_in_a_day = 24 * 60 * 60
puts "There are #{seconds_in_a_day} seconds in a day."

This will produce:

There are 86400 seconds in a day.

Backslash Notations (Common in Double-Quoted Strings)

Section titled “Backslash Notations (Common in Double-Quoted Strings)”

Common backslash escape sequences supported in double-quoted strings and similar contexts:

NotationCharacter Represented
\nNewline (0x0A)
\rCarriage return (0x0D)
\tHorizontal tab (0x09)
\fFormfeed (0x0C)
\bBackspace (0x08)
\aBell/Alert (0x07)
\eEscape (0x1B)
\sSpace (0x20)
\\Literal backslash
\'Literal single quote (useful in %Q{})
\"Literal double quote (useful in "...")
\nnnOctal notation (n being 0-7)
\xnnHexadecimal notation (n being 0-9, a-f, or A-F)
\u{nnnn ...}Unicode character(s) (e.g., \u{41 42 43} for “ABC”)
\unnnnUnicode character (exactly four hex digits)

For more details on Ruby Strings, including encoding and advanced methods, refer to the official Ruby documentation on the String class.

Array literals are created by placing a comma-separated series of object references between square brackets ([]). A trailing comma is ignored.

Example:

#!/usr/bin/env ruby
my_array = ["fred", 10, 3.14, "This is a string", "last element",]
my_array.each do |item|
puts item
end
# Word array literal (common for arrays of strings)
words = %w[this is a test]
puts words.inspect # => ["this", "is", "a", "test"]

This will produce (for the my_array part):

fred
10
3.14
This is a string
last element

For comprehensive information on arrays, see the Array class documentation.

Hash literals (also known as associative arrays or dictionaries) are created by placing a list of key-value pairs between curly braces ({}). Keys and values can be separated by => (hash rocket) or, if keys are symbols, by a colon : (Ruby 1.9+ syntax). A trailing comma is ignored.

Example:

#!/usr/bin/env ruby
# Old syntax (still valid) or when keys are not symbols
colors_hash_rocket = { "red" => 0xf00, "green" => 0x0f0, "blue" => 0x00f }
# Modern syntax for symbol keys (preferred)
colors_symbols = { red: 0xf00, green: 0x0f0, blue: 0x00f }
puts "Using hash rocket syntax:"
colors_hash_rocket.each do |key, value|
print "#{key} is #{value}\n"
end
puts "\nUsing symbol key syntax:"
colors_symbols.each do |key, value|
print "#{key} is #{value}\n"
end

This will produce:

Using hash rocket syntax:
red is 3840
green is 240
blue is 15
Using symbol key syntax:
red is 3840
green is 240
blue is 15

For more details on Hashes, consult the Hash class documentation.

A Range represents an interval of values with a start and an end. Ranges can be constructed using s..e (inclusive range) and s...e (exclusive range, excludes the end value), or with Range.new.

When used as an iterator, ranges yield each value in the sequence.

A range (1..5) includes values 1, 2, 3, 4, 5. A range (1...5) includes values 1, 2, 3, 4.

Example:

#!/usr/bin/env ruby
puts "Inclusive range:"
(10..15).each do |n|
print n, ' '
end
puts
puts "\nExclusive range:"
(10...15).each do |n|
print n, ' '
end
puts

This will produce:

Inclusive range:
10 11 12 13 14 15
Exclusive range:
10 11 12 13 14

For more information on Ranges, refer to the Range class documentation.