16

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
  • 1,273
  • 1
  • 14
  • 29
  • Also see "[What is the colon operator in Ruby?](http://stackoverflow.com/questions/6337897/what-is-the-colon-operator-in-ruby)". – the Tin Man Jul 24 '14 at 23:21

3 Answers3

18

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.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 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? – Cu1ture Jul 24 '14 at 21:32
  • 2
    `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. – tadman Jul 25 '14 at 16:39
6

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.

Dan
  • 1,274
  • 2
  • 15
  • 32
  • 4
    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. – Taywee Dec 26 '17 at 21:09
5

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.)

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 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. – Cameron Oct 03 '16 at 16:39
  • @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.) – mipadi Oct 03 '16 at 17:21