{ |one, step, back| }

Symbols Are Not Immutable Strings
27 Dec 05 - http://www.onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.red

Inevitably, every Ruby nuby asks the question “What are symbols?”, and the standard answer is “A Symbol is an immutable string”. I have some issues with that answer.

Every Nuby’s Question

Whenever someone asks “what are symbols” in the ruby-talk mailing list, the explaination almost always begins with “Symbols just immutable strings”, and then goes on to explain what symbols are good for and how they are used. Comparing them to something familiar (like a String) is a good pedagogical technique, but I’m left feeling that the answer leads the nuby down the wrong path to understanding.

Symbols aren’t Strings

First of all, symbols really aren’t immutable strings. Not even close. In fact, they aren’t Strings of any kind. This simple fact is easily demonstrated by the following:

  $ irb --simple-prompt
  >> sym = :symbol
  => :symbol
  >> sym.size
  NoMethodError: undefined method `size' for :symbol:Symbol
          from (irb):2
  >> sym[0,2]
  NoMethodError: undefined method `[]' for :symbol:Symbol
          from (irb):3

You can’t ask for the size of a symbol. You can’t ask for a substring of the symbol. You can’t do anything that you can do with strings on Symbols except (1) convert it to an integer (using to_i) and (2) convert it to a symbol (using to_sym). If a symbol is not a duck-type for a String, it hardly seems reasonable to call Symbols any kind of String, even immutable ones.

So if they aren’t Strings, what are they?

A Symbol is a simply an object that can be can be uniquely identified by its name. Every time you say :xyz in your code, you will be refering to an object (a symbol) that has the name “xyz”. There is only one Symbol with the name “xyz”, so all references to :xyz will refer to the same symbol1.

So you see, there is a tight relationship between Strings and Symbols. Every symbol has a string name (available via to_s). And every String can be asked for its corresponding symbol (via to_sym). Strings and Symbols are closely related, but they are not the same thing.

So, fundamentally, Symbols are just objects with names.

And when should we use Symbols?

Invariably, when presented with the “Symbols are immutable Strings” meme, the nuby will ask “So when do I use Strings and when do I use Symbols”? By pointing out that Symbols are not Strings at all, makes it clear. Use Strings whenever you need … umm … string-like behavior.

As we pointed earlier, Symbols are not even duck-typed strings. So using a symbol where you really want string-like behavior is a mistake. Rather, take a clue from the description of a symbol: an object with a name. It turns out that symbols are great for naming things. Use them whenever you need to name something in your code. For example:

  1. Naming keyword options in a method argument list
  2. Naming enumerated values (e.g. like enums in C).
  3. Naming options in an option hash table.

I’m sure other uses will come to your mind.

Some Closing Thoughts

Here’s how I like to express the difference between Strings and Symbols. Strings are about a sequence of characters. Symbols are about naming and identifying things.

There you have it.


I’m watching. Perhaps the next time this question comes up on ruby-talk, someone will say “A Symbol is an object with a name”. That would make my day.


1 For anyone familiar with Lisp, the simularities between Symbols and Atoms are obvious.