What is the function of symbol in ruby? what's difference between string and symbol? Why is it not a good idea to dynamically create a lot of symbols?
A simple rule of thumb is to use symbols every time you need internal identifiers. For Ruby < 2.2 only use symbols when they aren't generated dynamically, to avoid memory leaks.
Because symbols are immutable, Ruby doesn't have to allocate more memory for the same symbol. That is because it knows that once it put the value in memory, it will never be changed, so it can reuse it. You can easily see this by looking at their object IDs.
There are two main differences between String and Symbol in Ruby. 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.
Symbols are like strings but they are immutable - they can't be modified.
They are only put into memory once, making them very efficient to use for things like keys in hashes but they stay in memory until the program exits. This makes them a memory hog if you misuse them.
If you dynamically create lots of symbols, you are allocating a lot of memory that can't be freed until your program ends. You should only dynamically create symbols (using string.to_sym
) if you know you will:
As I said earlier, they are useful for things like hashes - where you care more about the identity of the variable than its value. Symbols, when correctly used, are a readable and efficient way to pass around identity.
I will explain what I mean about the immutability of symbols RE your comment.
Strings are like arrays; they can be modified in place:
12:17:44 ~$ irb irb(main):001:0> string = "Hello World!" => "Hello World!" irb(main):002:0> string[5] = 'z' => "z" irb(main):003:0> string => "HellozWorld!" irb(main):004:0>
Symbols are more like numbers; they can't be edited in place:
irb(main):011:0> symbol = :Hello_World => :Hello_World irb(main):012:0> symbol[5] = 'z' NoMethodError: undefined method `[]=' for :Hello_World:Symbol from (irb):12 from :0
A symbol is the same object and the same allocation of memory no matter where it is used:
>> :hello.object_id => 331068 >> a = :hello => :hello >> a.object_id => 331068 >> b = :hello => :hello >> b.object_id => 331068 >> a = "hello" => "hello" >> a.object_id => 2149256980 >> b = "hello" => "hello" >> b.object_id => 2149235120 >> b = "hell" + "o"
Two strings which are 'the same' in that they contain the same characters may not reference the same memory, which can be inefficient if you're using strings for, say, hashes.
So, symbols can be useful for reducing memory overhead. However - they are a memory leak waiting to happen, because symbols cannot be garbage collected once created. Creating thousands and thousands of symbols would allocate the memory and not be recoverable. Yikes!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With