I had good timing with one of rubyist yesterday. He asked me, what is major difference between Ruby string and symbols. Honestly speaking i had no words expect symbols definition(Symbols are immutable. Mutable objects can be changed after assignment while immutable objects can only be overwritten). Finally he explained me with a nice example, Again i googled and come up with few new addition. That what i want to explain here, May it will help some one.
All are self explanatory, put a comment if need more details.
1. Single word String and Symbol
1.9.2p320 :226 > “test”
=> “test”
1.9.2p320 :227 > :test
=> :test
2. Multiple words String and Symbol
1.9.2p320 :230 > “test string”
=> “test string”
1.9.2p320 :231 > :”test string”
=> :”test string”
3. Symbol may also contain special characters like string
1.9.2p320 :234 > :”test string #”
=> :”test string #”
1.9.2p320 :235 > :”test string $”
=> :”test string $”
4. Convert string to Symbol:
1.9.2p320 :239 > “I am Ruby developer”
=> “I am Ruby developer”
1.9.2p320 :240 > “I am Ruby developer”.to_sym
=> :”I am Ruby developer”
1.9.2p320 :241 > “I am Ruby developer”.intern
=> :”I am Ruby developer”
5. Convert symbol to String:
1.9.2p320 :244 > :”I am Rails developer”
=> :”I am Rails developer”
1.9.2p320 :245 > :”I am Rails developer”.to_s
=> “I am Rails developer”
6. Strings are mutable(Mutable objects can be changed after assignment):
1.9.2p320 :250 > text = “I belongs to the”
=> “I belongs to the”
1.9.2p320 :251 > puts text << ” India”
I belongs to the India
7. Symbols are immutable(immutable objects can only be overwritten):
1.9.2p320 :252 > text = :”I belongs to the”
=> :”I belongs to the”
1.9.2p320 :253 > puts text << :” India”
NoMethodError: undefined method `<<’ for :”I belongs to the”:Symbol
from (irb#1):253
8.Frozen Strings
We can freeze the String and thus making it immutable. Once a String is frozen it cannot be changed.
1.9.2p320 :277 > test = “This is ruby string”
=> “This is ruby string”
1.9.2p320 :278 > test.upcase!
=> “THIS IS RUBY STRING”
1.9.2p320 :280 > test.freeze
=> “THIS IS RUBY STRING”
1.9.2p320 :281 > test.downcase!
RuntimeError: can’t modify frozen string
from (irb#1):281:in `downcase!’
from (irb#1):281
9. String Performance:
Because Strings are mutable, the Ruby interpreter never knows what that String may hold in terms of data. As such, every String needs to have its own place in memory. We can see this by creating some Strings and printing their object id.
1.9.2p320 :295 > puts “This is string performance test”.object_id
76899900
=> nil
1.9.2p320 :296 > puts “This is string performance test”.object_id
76884690
=> nil
1.9.2p320 :297 > puts “This is string performance test”.object_id
76870210
=> nil
1.9.2p320 :298 > puts “This is string performance test”.object_id
76855080
=> nil
1.9.2p320 :299 > puts “This is string performance test”.object_id
76842070
=> nil
NOTE: Our object id’s will be different then the ones above.
What we see above might not seem like a big issue, but behind the scenes is some heavy waste. To understand why, we first have to understand what is going on under the hood. An abridged explanation is as follows:
- First, a new String object is instantiated with the value of
"This is string performance test".
- The Ruby interpreter needs to look at the heap (your computers memory), find a place to put the new string and keep track of it via its object id.
- The String is passed to the puts method, and output to the screen.
- The Ruby interpreter sees that the String will not be used again as it is not assigned to a variable, and marks it for destruction.
- Back to step one four more times.
Conclusion: In above example, we are creating a new object, storing and ultimately destroying.
10. Symbol Performance:
1.9.2p320 :301 > puts :”This is string performance test”.object_id
233758
=> nil
1.9.2p320 :302 > puts :”This is string performance test”.object_id
233758
=> nil
1.9.2p320 :303 >
1.9.2p320 :304 > puts :”This is string performance test”.object_id
233758
=> nil
1.9.2p320 :305 > puts :”This is string performance test”.object_id
233758
=> nil
1.9.2p320 :306 > puts :”This is string performance test”.object_id
233758
In above, every Symbol shares the same object id, and as such the same space on the heap. To further increase performance, Ruby will not mark Symbols for destruction, allowing you to reuse them again and again. As Symbols stay in memory throughout the programs operation, we can quickly snag them from memory instead of instantiating a new copy every time. In fact, Symbols are not only stored in memory, they are also keep track of via an optimized Symbols dictionary.
10. We can see all Symbol by running the below command.
1.9.2p320 :340 > puts Symbol.all_symbols.inspect
[:example, :"test string", :"test string #", :"test string $", :"I am Ruby developer", :"I am Rails developer", :"I belongs to the", :" India", :text=, :"This is string performance test"]
Conclusion:
In ruby programming language, We should to use Symbol as much as we can instead of String, To optimize performance and save memory.
example:
hash = {“a” => “something”, “b” => “else”}
hash1 = {:a => “something”, :b => “else”}
I hope it will help to understand String and Symbol, shot a comment if i missed any things
19.311143
85.781250