What is the difference between a symbol and a variable in Ruby?
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.)
Related videos on Youtube
Cu1ture
Updated on June 09, 2022Comments
-
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.
-
PJP almost 10 yearsAlso see "What is the colon operator in Ruby?".
-
-
Cu1ture almost 10 yearsThanks 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 almost 10 years
attr_accessor :example
means "define a read/write attribute named 'example'" and defines the methodexample
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". Theattr_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 over 7 yearsWould 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 over 7 years@Cameron: Well, in the case of something like
a = "string", b = a
, yes. In the case ofa = "string"; b = "string"
, two objects with the contents "string" will be created. (I'm not sure how JS handles this.) -
Taywee over 6 yearsI'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.