What's the difference between a string and a symbol in Ruby?

29,327

Solution 1

The main difference is that multiple symbols representing a single value are identical whereas this is not true with strings. For example:

irb(main):007:0> :test.object_id
=> 83618
irb(main):008:0> :test.object_id
=> 83618
irb(main):009:0> :test.object_id
=> 83618

Those are three references to the symbol :test, which are all the same object.

irb(main):010:0> "test".object_id
=> -605770378
irb(main):011:0> "test".object_id
=> -605779298
irb(main):012:0> "test".object_id
=> -605784948

Those are three references to the string "test", but are all different objects.

This means that using symbols can potentially save a good bit of memory depending on the application. It is also faster to compare symbols for equality since they are the same object, comparing identical strings is much slower since the string values need to be compared instead of just the object ids.

As far as when to use which, I usually use strings for almost everything except things like hash keys where I really want a unique identifier, not a string.

Solution 2

What are the differences between Symbols and Strings?

  1. Symbols are immutable: Their value remains constant.
  2. Multiple uses of the same symbol have the same object ID and are the same object compared to string which will be a different object with unique object ID, everytime.
  3. You can't call any of the String methods like split on Symbols.

From Understanding Differences Between Symbols & Strings in Ruby

If you know Chinese, you can also read 理解 Ruby Symbol.

Solution 3

The statement:

foo = "bar"

creates a new object in memory. If we repeat the statement:

foo = "bar"

We create another object.

To understand it more clearly please try this code in IRB:

foo = "bar"
puts "string #{foo} with object id = #{foo.object_id}"
foo = "bar"
puts "string #{foo} with object id = #{foo.object_id}"

You will get output like:

string bar with object id = 70358547221180
string bar with object id = 70358548927060

which clearly shows there are two different object for the same string. Now if you use a symbol it will create one object per symbol so:

foo = :bar
puts "symbol #{foo} with object id = #{foo.object_id}"
foo = :bar
puts "symbol #{foo} with object id = #{foo.object_id}"

shows:

symbol bar with object id = 7523228
symbol bar with object id = 7523228

which means there is only one object for :bar.

Further, Symbols are immutable and you can't call any of the String methods like upcase or split on Symbols.

Comparing Symbols are faster than comparing Strings. Symbols can be thought of as constant/immutable strings that form a unique set that are effectively converted to memory pointers on the heap. This means comparing two symbols is fast because you are just comparing two integers (memory pointers).

Strings are mutable so the memory pointer to their value on the heap can change after modification. This means comparison operations are slower because duplicates can exist that are semantically equivalent.

Use a symbol when you are sure that the value will remain constant, for example use symbols for hash keys. Use a string when you want to change the value or want to use a string method on it.

Solution 4

An additional difference between String and Symbol is that a String has a lot more methods on it for string manipulation, while a Symbol is a relatively lean object.

Check out the documentation for the String class and the Symbol class.

Solution 5

There are two main differences between String and Symbol in Ruby.

  1. String is mutable and Symbol is not:

    • Because the String is mutable, it can be change in somewhere and can lead to the result is not correct.
    • Symbol is immutable.
  2. String is an Object so it needs memory allocation

    puts "abc".object_id # 70322858612020
    puts "abc".object_id # 70322846847380
    puts "abc".object_id # 70322846815460
    

    In the other hand, Symbol will return the same object:

    puts :abc.object_id # 1147868
    puts :abc.object_id # 1147868
    puts :abc.object_id # 1147868
    

So the String will take more time to use and to compare than Symbol.

Read "The Difference Between Ruby Symbols and Strings" for more information.

Share:
29,327
readonly
Author by

readonly

Readonly

Updated on July 05, 2022

Comments

  • readonly
    readonly almost 2 years

    What's the difference between a string and a symbol in Ruby and when should I use one over the other?

  • Dominik Grabiec
    Dominik Grabiec over 15 years
    Although symbols are not cleaned up by the garbage collector and stick around until the end of the runtime instance. So if you declare a lot of symbols you might be wasting a lot of memory.
  • Pistos
    Pistos over 15 years
    @Daemin: This is generally a non-issue unless you are dynamically creating symbols en-masse. This is the cause of memory ballooning in some apps. If you use hard-coded symbols in your code, you are relatively safe.
  • Devplex
    Devplex over 11 years
    I'm not sure I understand your first sentence. When people say each snowflake is unique, it means each one is different. Every occurrence is different from the other. However in your symbol code example you show each occurrence to be exactly the same object. Would 'identical' not be a better word?
  • PJP
    PJP almost 5 years
    When supplying a link, please summarize the important information from the page and supply an attribution. Links rot then break, resulting in information that isn't useful. "How to reference material written by others" will help explain.
  • PJP
    PJP almost 5 years
    Please read "How to reference material written by others". The link is broken.
  • mfaani
    mfaani over 3 years
    I know how to create a string something = “test”. How do I do that for a symbol? Can you add something to your answer?
  • Ali
    Ali over 3 years
    @Honey - you can do something = :test