A comment in Ruby on Rails (and in programming in general) is a piece of text that is ignored by the interpreter when executing the code. Comments are used to provide explanations, documentation, or notes within the code to make it more understandable.
In Ruby, there is a special type of comment called a magic comment. They provide instructions or directives to the Ruby interpreter at runtime. The magic comments influence the behavior of the interpreter, enabling or disabling certain features or configurations for the code in the file.
The frozen string literal is probably the most commonly used magic comment. Let’s dive in and explore a few aspects of this magic comment to understand why you should use it whenever possible.
Immutability
The immutability enforced by frozen_string_literal: true
ensures that once a string literal is defined, its content cannot be altered, making it safer to work with and preventing accidental modifications that may lead to bugs or unexpected behavior in your Ruby code.
1
2
3
4
5
6
7
8
| # Without frozen_string_literal: true
str = "Hello, world!"
str[0] = "H"
puts str
#=> Hello, world!
|
1
2
3
4
5
6
7
8
9
| # With frozen_string_literal: true
# frozen_string_literal: true
str = "Hello, world!"
str.freeze
str[0] = "H"
#=> Error: can't modify frozen String
|
1
2
3
4
5
6
7
| # frozen_string_literal: true
greeting = "Hello, "
name = "John"
greeting.concat(name)
# This will raise a RuntimeError: can't modify frozen String
|
Reduce the program’s execution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Without frozen_string_literal: true
require 'benchmark'
def perform_without_frozen_string_literal
result = ""
100000.times do |i|
result += "Number #{i}, "
end
result
end
time_without_frozen = Benchmark.realtime do
perform_without_frozen_string_literal
end
puts "Time without frozen_string_literal: #{time_without_frozen} seconds"
#=> Time without frozen_string_literal: 16.094440577999194 seconds
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # With frozen_string_literal: true
# frozen_string_literal: true
require 'benchmark'
def perform_with_frozen_string_literal
result = ""
100000.times do |i|
result += "Number #{i}, "
end
result
end
time_with_frozen = Benchmark.realtime do
perform_with_frozen_string_literal
end
puts "Time with frozen_string_literal: #{time_with_frozen} seconds"
#=> Time with frozen_string_literal: 15.284278884000742 seconds
|
Allocates the same space for the same string
Freezing a string literal in Ruby has a two-fold benefit: enhanced application performance and efficient memory usage. When you freeze a string literal, you instruct Ruby not to allow any modifications to that string object.
By preventing modifications, Ruby can avoid the need to allocate new memory space for the same string, which leads to better application performance. Additionally, freezing reduces the burden on garbage collection tasks, saving time and resources.
1
2
3
4
5
6
7
8
9
10
11
12
| # Without frozen_string_literal: true
def hello_id
a = 'hello'
a.object_id
end
puts hello_id
puts hello_id
#=> 70244568358640
#=> 70244568358500
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # With frozen_string_literal: true
# frozen_string_literal: true
def hello_id
a = 'hello'
a.object_id
end
puts hello_id
puts hello_id
#=> 70244568358640
#=> 70244568358640
|