# What is a symbol in Ruby, and when should I use one instead of a string?

Source: https://poignantguide.net/answers/read/what-is-a-symbol-in-ruby-and-when-should-i-use-one-instead-of-a-string/
Site: Poignant Guide Ruby Q&A, category Ruby syntax and basics
Published: 2026-11-14. Updated: 2026-11-14. Replies: 0.

## Question by Odile Marchetti (staff), 2026-11-14

A symbol is a name that Ruby keeps as one shared object, written with a colon like :name. Use a symbol for labels that identify something, such as hash keys, options and statuses. Use a string for text that can change or that a person reads. Equal symbols are the same object; equal strings are separate objects.

## A minimal example

A **string** is a piece of text in quotes. A **hash** is a collection of key and value pairs, written between braces. Here a hash uses symbols as keys:

```ruby
person = { name: "Ada", city: "London" }

p person[:name]    # => "Ada"
p person["name"]   # => nil
p person.keys      # => [:name, :city]
```

The second lookup returns `nil` because the key is the symbol `:name`, not the string `"name"`. Ruby treats those as different things, and that one fact causes most symbol confusion.

The [Ruby documentation for Symbol](https://docs.ruby-lang.org/en/3.3/Symbol.html) puts it this way: Symbol objects represent identifiers inside the interpreter, while String objects represent text or data. An **identifier** is a name your program uses for something, like a method or a variable.

## Why a symbol is different from a string

The same documentation says that the same Symbol object is created for a given name for the whole run of a program. You can see this with `equal?`, which asks whether two variables point at the very same object:

```ruby
p :ruby.equal?(:ruby)        # => true
a = "ruby"
b = "ruby"
p a.equal?(b)                # => false
p a == b                     # => true
```

Two strings with the same letters are equal in value but are two separate objects. Two copies of `:ruby` are one object. A symbol is also not something you edit. You can add letters to a string with `<<`, but a symbol has no such method, because it is a label and not a piece of text to change.

You can convert in both directions:

```ruby
p :name.to_s          # => "name"
p "name".to_sym       # => :name
p "hello world".to_sym  # => :"hello world"
```

The last line shows that a symbol can hold spaces; Ruby then writes it with quotes after the colon, as the literals page describes.

## Which should I use?

| Situation | Use | Why |
|---|---|---|
| Hash keys you write in your own code | Symbol | Short, and the same object every time |
| Options and keyword arguments | Symbol | The `key: value` syntax is the same as for symbol keys in a hash |
| A status such as :active or :paused | Symbol | A fixed label, not text to show |
| A name or message a person will read | String | It is text, and you may build or change it |
| Data that arrives from a form, a file or a web request | String | Outside data is text until you convert it |

The [syntax documentation for literals](https://docs.ruby-lang.org/en/3.3/syntax/literals_rdoc.html) shows the hash form `{ a: 1, b: 2 }` and notes that the same syntax is used for keyword arguments in a method call. A keyword argument is a named input you pass like `greet(name: "Ada")`.

## Older and newer forms

Code from the guide's era often writes hashes with a hash rocket, as in `{ :name => "Ada" }`. That form still works in Ruby 3.3. The `name: "Ada"` form is the shorter way to write the same thing. If you want a string key you must keep the rocket: `{ "name" => "Ada" }`.

## Mistakes beginners make

1. **Looking up the wrong kind of key.** A hash built with `:name` is not found by `"name"`. Check with `p hash.keys`; if you see colons, use symbols.
2. **Using symbols for text.** A greeting or a sentence is not a label. If you plan to join it, shout it or print it, make it a string.
3. **Converting everything to symbols.** If the data came from a user, keep it as a string. Convert only when you need a fixed set of labels.
4. **Mixing the two in one hash.** `{ name: "Ada", "age" => 36 }` is legal and confusing. Pick one style per hash.

## Check this in order

1. Does your lookup return `nil` when you expected a value? Run `p hash.keys`.
2. Are the keys printed with a colon, such as `:name`? Then look them up with a colon.
3. Are the keys in quotes, such as `"name"`? Then look them up with quotes.
4. Did the data come from outside your program? Convert once, in one place, with `to_sym` or `transform_keys(&:to_sym)`.

To see what `p` prints for a symbol versus `puts`, read [What is the difference between puts, print and p in Ruby?](/answers/read/what-is-the-difference-between-puts-print-and-p-in-ruby/), and if you have not set Ruby up yet, start with [How do I install Ruby on a Mac with Homebrew and rbenv?](/answers/read/how-do-i-install-ruby-on-a-mac-with-homebrew-and-rbenv/). Keep [Chapter 3](https://poignantguide.net/ruby/chapter-3.html) of the guide open while you try these lines in irb.

Checked on 12 November 2026.

---
Cite as: Poignant Guide Ruby Q&A, "What is a symbol in Ruby, and when should I use one instead of a string?", https://poignantguide.net/answers/read/what-is-a-symbol-in-ruby-and-when-should-i-use-one-instead-of-a-string/, accessed 2026-11-15.
