Question
In Ruby, what does the colon mean in a hash such as this?
{ :bla => 1, :bloop => 2 }
I understand that :bla is related to a symbol and that symbols are somewhat like strings, but I am not clear on what a symbol is or why it is used here. Could someone explain the concept?
Short Answer
Ruby uses a leading colon to create a symbol, such as :bla. A symbol is an immutable name-like value commonly used for identifiers, hash keys, method names, and configuration options. In { :bla => 1 }, :bla is the key and 1 is its associated value.
Concept
A colon in :bla creates a Ruby symbol literal. The symbol is :bla; the colon is part of the syntax used to write it.
status = :active
Symbols represent stable names or labels. They are especially useful when Ruby needs an identifier rather than changing text.
In this hash:
{ :bla => 1, :bloop => 2 }
:blais a symbol used as a key.=>associates that key with the value1.:bloopis another symbol key associated with2.
This is equivalent to:
settings = {
:bla => 1,
:bloop => 2
}
puts settings[:bla] # 1
Symbols resemble strings because both can contain text-like names. However, a string is usually used as text data that may be read, displayed, or changed. A symbol is usually used as a fixed label or identifier.
"active" # text
:active # identifier-like label
Symbols matter because Ruby APIs frequently use names to describe choices, states, keys, and methods. For example, :json, :email, :pending, and :name communicate meaning without representing user-facing text.
Mental Model
Think of a string as the writing on a sheet of paper and a symbol as a permanent label on a filing drawer.
"name"is text you might display, combine, or edit.:nameis a label that says, “this drawer is called name.”
A hash works like a set of labelled drawers:
user = { :name => "Ada", :role => :admin }
The :name label points to the value "Ada". The :role label points to another label, :admin, which represents a role choice rather than display text.
Syntax and Examples
A symbol usually starts with a colon:
:name
:pending
:send_email
Use quotes when the symbol name contains characters that are not valid in a normal Ruby identifier:
:"full name"
:"not-valid-as-a-normal-identifier!"
Symbols as hash keys
Older Ruby code often uses the hash rocket syntax:
person = {
:name => "Mina",
:age => 28
}
puts person[:name] # Mina
Modern Ruby commonly uses the shorter label syntax for symbol keys:
person = {
name: "Mina",
age: 28
}
puts person[:age] # 28
Here, name: means the symbol key :name. It is shorthand for :name =>.
Symbols compared with strings
text = "hello"
label = :hello
puts text.class # String
puts label.class # Symbol
puts label.to_s # hello
puts "hello".to_sym # hello (a Symbol)
Use strings for text content. Use symbols for fixed names, categories, and keys when the API expects symbols.
Step by Step Execution
Consider this code:
account = {
status: :active,
plan: "pro"
}
if account[:status] == :active
puts "Account can use member features."
end
Step by step:
- Ruby creates a hash named
account. status:is shorthand for the symbol key:status.- The value stored under
:statusis the symbol:active. plan:is shorthand for:plan, and its value is the string"pro".account[:status]looks up the value stored under the:statuskey.- That lookup returns
:active. - Ruby compares
:active == :active, which is true. - Ruby prints the message.
The hash can be written in the longer form with the same result:
account = {
:status => :active,
:plan => "pro"
}
Real World Use Cases
Symbols are common whenever code needs a small, fixed set of names.
Configuration options
options = { timeout: 10, format: :json }
:json identifies a format choice. It is not necessarily text to show to a user.
Application states
order_status = :shipped
An order can have known states such as :pending, :paid, :shipped, or :cancelled.
Method names
"ruby".send(:upcase) # "RUBY"
:upcase names the method Ruby should call.
Data returned by APIs or libraries
result = { ok: true, error: nil }
if result[:ok]
puts "Request succeeded"
end
Symbol keys make structured program data convenient to access.
Framework parameters
Many Ruby libraries accept option hashes:
sleep_duration = 2
# Example shape used by many APIs:
# connect(host: "localhost", timeout: sleep_duration)
The method receives named options such as :host and :timeout.
Real Codebase Usage
In real Ruby projects, symbols are often used for internal names and strings for external text.
Named keyword arguments
Modern Ruby methods frequently use keyword arguments, which are named with symbols internally:
def create_user(name:, role: :member)
{ name: name, role: role }
end
user = create_user(name: "Ava", role: :admin)
name: and role: make calls readable and prevent confusion about argument order.
Guard clauses with state symbols
def send_receipt(order)
return unless order[:status] == :paid
puts "Sending receipt"
end
A symbol such as :paid makes a finite state check explicit.
Validation results
def validate_email(email)
return :missing if email.nil? || email.empty?
return :invalid unless email.include?("@")
:valid
end
The caller can compare the result against known labels:
result = validate_email("ava@example.com")
puts "Accepted" if result == :valid
Converting external JSON-style keys only when needed
JSON data often has string keys because JSON object keys are strings. Ruby code may convert keys to symbols when it deliberately wants a symbol-keyed internal structure. Avoid converting arbitrary, untrusted keys to symbols without a reason; retain strings if the external data is naturally string-keyed.
Common Mistakes
Treating a symbol and a string as equal
They are different objects and do not compare equal.
:status == "status" # false
Use the same key type consistently:
data = { status: "active" }
data[:status] # "active"
data["status"] # nil
Forgetting the colon during a hash lookup
user = { name: "Lee" }
user[name] # Broken: Ruby looks for a variable named name
Use a symbol literal:
user[:name] # "Lee"
Confusing :name with name:
:nameis a symbol value.name:is hash-key shorthand and must be followed by a value in a hash or keyword argument context.
label = :name
person = { name: "Lee" }
Using symbols for text that must be edited
Symbols are immutable. This will fail:
word = :hello
word << "!" # NoMethodError
Use a string for editable text:
word = "hello"
word << "!"
Assuming => creates a symbol
The => operator associates a key with a value in a hash. The leading colon creates the symbol.
{ :name => "Lee" }
# ^ symbol ^ associates key and value
Comparisons
| Form | Meaning | Typical use |
|---|---|---|
:name | A Symbol literal | Identifiers, states, hash keys, method names |
"name" | A String literal | Display text, user input, file contents |
:name => "Ada" | Older hash key/value syntax | Existing or older Ruby code |
name: "Ada" | Modern shorthand for :name => "Ada" | Most current Ruby code |
hash[:name] | Looks up a symbol key | Hash created with name: or :name => |
hash["name"] | Looks up a string key | Data with string keys, such as parsed JSON |
Hash rocket versus modern shorthand
# Equivalent hashes
old_style = { :color => "blue" }
new_style = { color: "blue" }
Prefer color: "blue" in new code when the key is a normal identifier. You may still see => when working with older code or keys that need a special form:
headers = { "Content-Type" => "application/json" }
Cheat Sheet
# Create symbols
:ready
:send_email
:"full name"
# Symbol-keyed hashes
user = { :name => "Noor" } # older syntax
user = { name: "Noor" } # modern syntax
# Read a symbol key
user[:name] # "Noor"
# String and symbol are different
:name == "name" # false
# Convert deliberately
:name.to_s # "name"
"name".to_sym # :name
# Method name as a symbol
"hello".send(:upcase) # "HELLO"
Rules to remember:
:wordis aSymbol.word:is shorthand for:word =>in a hash or keyword argument list.- Use the key type that the hash actually contains:
:nameand"name"are different keys. - Use strings for mutable or user-visible text; use symbols for fixed internal labels.
FAQ
What does the colon do in Ruby?
Before a name, as in :name, it creates a symbol literal. In name: "Ada", it is part of Ruby's shorthand syntax for a symbol hash key.
Is a Ruby symbol just a string?
No. Symbols and strings can contain similar characters, but they are different types. A symbol is an immutable identifier-like value; a string is text data.
Why are symbols used as hash keys in Ruby?
They clearly express that a key is a fixed internal name, such as :name, :status, or :timeout. Ruby conventions and many APIs use symbol keys.
Are :name => "Ada" and name: "Ada" the same?
For a normal identifier-like key, yes. Both create a hash with the symbol key :name.
Why does hash["name"] return nil when hash[:name] works?
A string and a symbol are different hash keys. If the hash uses :name, look it up with hash[:name].
When should I use a string instead of a symbol?
Use a string for text you display, receive from users, read from files, or need to modify. Use a symbol for fixed labels and internal identifiers.
Can a symbol contain spaces or punctuation?
Yes, using quoted symbol syntax:
:"full name"
However, simple symbols such as :name are usually clearer when possible.
Mini Project
Description
Build a small order-status checker. It stores order details in a symbol-keyed hash and uses symbols to represent a fixed set of order states. This mirrors how applications commonly model internal state.
Goal
Create a method that returns a useful message for an order based on its symbol status.
Requirements
- Create an order hash with
id,customer, andstatussymbol keys. - Use a symbol such as
:pending,:paid,:shipped, or:cancelledas the status value. - Write an
order_messagemethod that receives an order hash. - Return a different message for each known status.
- Return a fallback message for an unknown status.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.