What is Frozen String Literal
We have seen this comment # frozen_string_literal: true in our Ruby files,
have you ever wondered what exactly this comment does?
In Ruby, a literal string is a sequence of characters enclosed in single (‘’) or double (“”) quotes. These strings are mutable, meaning their contents can be modified after creation.
The magic comment # frozen_string_literal: true in Ruby instructs the Ruby
interpreter to freeze all string literals. This means that each string literal is
allocated memory only once and cannot be modified.
This improves memory efficiency and prevents accidental changes to string values throughout the program.
Magic comments are special comments in Ruby that are specified on top of the file. They influence how the Ruby code is executed, essentially providing instructions for the Ruby interpreter to follow specific behaviors based on the comments provided.
Note: The magic comment # frozen_string_literal: true was supported first time in Ruby 2.3
Now let’s see in the example below how the String is mutable.”
str = "Ruby"
str << " on Rails"
puts str # Ruby on RailsBut when we use a frozen literal string comment, we get the FrozenError
# frozen_string_literal: true
str = "Ruby"
str << " on Rails"
puts str
# `<main>': can't modify frozen String: "Ruby" (FrozenError)As we have mentioned before it improves memory efficiency as well, memory allocations, which means memory should be allocated only once for each string literal.
We can see below that if we are not using the magic comment then allocated memory is different for the same string.
puts "Ruby".object_id # 6012399
puts "Ruby".object_id # 8239934But when we use the magic comment, it allocates the memory only once for the same string. In the below example, we can see that the object_id is the same for the string “Ruby on Rails” every time.
# frozen_string_literal: true
puts "Ruby on Rails".object_id # 6012399
puts "Ruby on Rails".object_id # 6012399
puts "Ruby on Rails".object_id # 6012399Ruby 3.4 introduces “Chilled Strings”
Ruby 3.4 introduces
a new intermediate string state called chilled strings. String literals in files
without a # frozen_string_literal: true comment are compiled as chilled strings.
Chilled strings are still mutable — mutations succeed as before. However, mutating a chilled string emits a deprecation warning.
The warnings are not emitted by default. To enable them, set Warning[:deprecated] = true.
Deprecation warnings are only useful during development and should not be displayed
continuously in production.
Warning[:deprecated] = true
str = "Ruby"
str << " on Rails"
# warning: literal string will be frozen in the future
puts str # Ruby on Rails (mutation still succeeds)
puts str.frozen? # falseOpt-out options:
- Per-file: add
# frozen_string_literal: falseat the top of the file - Globally: use the
--disable-frozen-string-literalcommand line flag
Debugging: If you need to trace where a chilled string was allocated, use the
--debug-frozen-string-literal flag, which adds allocation source information to the warning.
Adding the magic comment # frozen_string_literal: true to your files is the
recommended way to benefit from frozen string optimizations and avoid these warnings.
Please go through this link to read more about it.
Note: The chilled strings feature has continued to evolve since this post was written.
The early implementation returned true for #frozen?, which was later changed to false,
and additional changes have been made in subsequent versions.
