Symbols
Symbols are lightweight, immutable identifiers in Ruby. They start with a colon โ :name is a symbol. Unlike strings, symbols are interned, meaning Ruby stores only one copy of each unique symbol in memory. This makes them perfect for hash keys, method names, and identifiers.
:name # => :name
:hello_world # => :hello_world
:"with spaces" # => :"with spaces"
puts :name.class # => Symbol
puts :name.object_id # => same every time it's used
Try it Yourself ->
Symbols as Hash Keys
Symbols are the preferred hash keys in Ruby. They're faster to compare than strings because each symbol is a unique integer. Rails uses symbol keys extensively for configuration and options.
person = {
name: "Alice",
age: 30,
city: "Portland"
}
puts person[:name] # => "Alice"
puts person[:age] # => 30
# These are equivalent:
{ :name => "Alice" } # Old syntax
{ name: "Alice" } # New syntax (Ruby 1.9+)
# Symbols are faster for hash lookup
large_hash = {}
10000.times { |i| large_hash[:"key_#{i}"] = i }
puts large_hash[:key_5000] # => 5000
Try it Yourself ->
Converting Between Symbols and Strings
Use to_sym to convert a string to a symbol, and to_s to convert a symbol to a string. This comes up often when dealing with dynamic method names or hash keys.
str = "hello"
sym = str.to_sym
puts sym # => :hello
back_to_str = sym.to_s
puts back_to_str # => "hello"
# Dynamic symbol creation
method_name = "greet"
puts method_name.to_sym # => :greet
# Symbol interpolation (Ruby 2.0+)
name = "Alice"
:"#{name}_greeting" # => :"Alice_greeting"
Try it Yourself ->
Symbols as Method Identifiers
Symbols are used to reference methods throughout Ruby. When you call send with a method name, you pass a symbol. attr_reader, attr_writer, and attr_accessor all take symbols. This is the foundation of Ruby's metaprogramming.
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
def greet
"Hi, I'm #{name}"
end
end
person = Person.new("Alice", 30)
# send calls a method by symbol name
puts person.send(:greet) # => "Hi, I'm Alice"
puts person.send(:name) # => "Alice"
# Check if a method exists
puts person.respond_to?(:greet) # => true
puts person.respond_to?(:fly) # => false
Try it Yourself ->
When to Use Symbols vs Strings
Use symbols when the value is an identifier โ method names, hash keys for configuration, enum-like values. Use strings when the value is actual data โ user input, file contents, text to display. Symbols are for code. Strings are for data.
# Good: symbols for identifiers
status = :active
role = :admin
config = { host: "localhost", port: 3000 }
# Good: strings for data
user_name = gets.chomp
file_content = File.read("data.txt")
greeting = "Hello, World!"
# Symbol.all_symbols shows all symbols in use
puts Symbol.all_symbols.length # => large number (includes built-ins)
puts Symbol.all_symbols.sample(5) # => random sample
Try it Yourself ->