Exploring 'Frozen String Literal': A Ruby Magic Comment

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