What is the difference between a symbol and a variable in Ruby?

10,497

Solution 1

A symbol is an "internalized" string, it's more like a constant than anything. Typical example:

account_details = {
  :name => 'Bob',
  :age => 20
}

Here the symbols :name and :age are keys for a hash. They are not to be confused with variables. account_details is a variable.

A variable in Ruby is a handle to an object of some sort, and that object may be a symbol.

Normally you employ symbols when using strings would result in a lot of repetition. Keep in mind that strings are generally distinct objects where a distinct symbol always refers to the same object, making them more efficient if used frequently.

Compare:

"string".object_id == "string".object_id
# => false

:string.object_id == :string.object_id
# => true

Even though those two strings are identical, they're independent string objects. When used as keys for hashes, arguments to methods, and other common cases, these objects will quickly clutter up your memory with massive amounts of duplication unless you go out of your way to use the same string instance. Symbols do this for you automatically.

Solution 2

Variables hold a reference to an object. For example, variables can reference strings and symbols like:

a = 'foo'
b = :bar

In Ruby string are mutable, it means that you can change them: 'foo' + 'bar' will give a concatenated string. You can perceive symbols as immutable strings, it means that you cannot change a symbol: :foo + :bar will give you an error. Most importantly, the same symbols hold reference to the same object:

a = :foo
b = :foo
a.object_id # => 538728
b.object_id # => 538728

This increases performance in hash lookups and other operations.

Solution 3

They're pretty different. Variables give a label to an object. Symbols are more like strings, except that they're immutable and interned in memory, so that multiple references to the same symbol don't use extra memory. (Contrast this with strings, where multiple references to the same string of characters will result in multiple copies of the string.)

Share:
10,497

Related videos on Youtube

Cu1ture
Author by

Cu1ture

Updated on June 09, 2022

Comments

  • Cu1ture
    Cu1ture almost 2 years

    I am trying to understand what the difference is between a symbol and a variable in ruby. They seemed to do the exact same thing in giving a name that references an object.

    I have read that symbols alow for faster programs but I am not sure why or how they are different from variables in any way.

  • Cu1ture
    Cu1ture almost 10 years
    Thanks for the reply, I think my confusion is coming from the use of Symbols with Attributes. When writing an Attribute reader for an instance variable a symbol is used in the Attribute, but a Variable is returned. How does the symbol relate to the instance variable in this case?
  • tadman
    tadman almost 10 years
    attr_accessor :example means "define a read/write attribute named 'example'" and defines the method example and example=` as well as the instance variable @example. The argument is passed in as a symbol so the receiving method can tell what it is. Remember that variable names are local, the name of a variable is never passed in. attr_reader example means "create a reader with whatever the variable example wants it to be called". The attr_reader function has no way of knowing your variable's name. The relationship here is the symbol is used to communicate the desired name.
  • Cameron
    Cameron over 7 years
    Would referencing the string via a variable not do the same thing and keep one instance in memory? The same as using variables in JS to prevent duplication and only getting the same data once.
  • mipadi
    mipadi over 7 years
    @Cameron: Well, in the case of something like a = "string", b = a, yes. In the case of a = "string"; b = "string", two objects with the contents "string" will be created. (I'm not sure how JS handles this.)
  • Taywee
    Taywee over 6 years
    I'd like to point out for future readers that being able to add two objects to get another object out does not mean that the object is mutable. Strings in Python and Lua are immutable; adding two of them gives you another object out. In Ruby, strings are mutable, but adding two of them does not change either of the base strings, it gives you a new string object.