Ruby 3.0 Added name Method For Symbols

September 11, 2020

In Ruby, symbols are immutable and strings are mutable.

:football.frozen? #=> true :football.to_s.frozen? #=> false # Ruby 3.0.0 :football.name.frozen? #=> true

If we define a symbol once, then a single memory location is referred everywhere.
In short, symbols help us to reduce memory allocations.

Rubyists use symbols and strings interchangeably in many places.

Let's see an example:

def game(sport) 3.times do s = sport puts s + " is my fav game!" puts s.object_id end end game(:football) #=> NoMethodError (undefined method `+' for :football:Symbol)

To fix the above error, we can use to_s method to convert the symbol :football to a string "football".

Let's fix the above example:

def game(sport) 3.times do s = sport.to_s puts s + " is my fav game!" puts s.object_id end end game(:football) # output #=> football is my fav game! #=> 240 #=> football is my fav game! #=> 260 #=> football is my fav game! #=> 280

Good that we fixed the error but there is a memory allocation overhead.

By using to_s for a symbol :football within a loop, we unnecessarily created three new mutable strings and Ruby internally allocated separate memory locations as indicated by object_id (240, 260, 280).

Before Ruby 3.0, we can handle this memory allocation issue as below: (mark the -sport.to_s line)

def game(sport) 3.times do s = -sport.to_s puts s + " is my fav game!" puts s.object_id end end game(:football)

But using -@ is not very readable and it does not offer a consistent syntax either.

For example:

10.to_s #=> "10" # unexpected result -10.to_s #=> "-10" -10.to_s.frozen? #=> false # inconsistent syntax to get desired result -(10).to_s #=> "10" -(10).to_s.frozen? #=> true -true.to_s #=> "true" # error while chaining methods -true.to_s.frozen? -(true).to_s.frozen? #=> NoMethodError (undefined method `-@' for true:TrueClass)

Finally, Ruby 3.0.0 has introduced Symbol#name method which will return the name of the symbol as a frozen string.
This will significantly reduce memory allocations for projects in Rails.

Let's see how it helps in minimizing memory allocation in our example:

def game(sport) 3.times do s = sport.to_s puts s + " is my fav game!" puts s.object_id end end # output #=> football is my fav game! #=> 300 #=> football is my fav game! #=> 300 #=> football is my fav game! #=> 300

As we can see above, Ruby did not create a new string each time rather it just created the string in memory once and refers every time it is used.

However it is still worth debating whether Ruby should have introduced another method name for symbols or should have changed behavior of existing Symbol#to_s method to return a frozen string.

If we want existing Symbol#to_s method to return frozen strings by default, we can use symbol-fstring gem as of now.

This is the link to the relevant discussion.

Got something to share with us ? Please inbox

info@scriptday.com

© All rights reserved 2020