What does the comment "frozen_string_literal: true" do?

This is rspec binstub in my project directory.

 #!/usr/bin/env ruby begin load File.expand_path("../spring", __FILE__) rescue LoadError end # frozen_string_literal: true # # This file was generated by Bundler. # # The application 'rspec' is installed as part of a gem, and # this file is here to facilitate running it. # require "pathname" ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath) require "rubygems" require "bundler/setup" load Gem.bin_path("rspec-core", "rspec") 

What does it mean?

 # frozen_string_literal: true 
+147
string immutability ruby
Jun 13 '16 at 21:18
source share
3 answers

# frozen_string_literal: true is a magical comment first supported in Ruby 2.3 that tells Ruby that all string literals in a file are implicitly frozen, as if #freeze were called for each of them. That is, if a string literal is defined in a file with this comment, and you call a method for this string that modifies it, for example << , you will get RuntimeError: can't modify frozen String .

The comment should be in the first line of the file.

In Ruby 2.3, this magic commentary can be used to prepare for fixed string literals, which are used by default in Ruby 3 .

In Ruby 2.3, it starts with --enable=frozen-string-literal , and in Ruby 3, string literals are committed to all files. You can override the global setting with # frozen_string_literal: false .

If you want the string literal to be mutable regardless of global or file settings, you can prefix it with the unary + operator (carefully with operator precedence) or call .dup for it:

 # frozen_string_literal: true "".frozen? => true (+"").frozen? => false "".dup.frozen? => false 

You can also freeze a mutable (non-freezing) string with unary - .

+221
Jun 13 '16 at 21:26
source share
β€” -

In Ruby 3.0. Matz (the creator of Rubys) decided to make all string literals frozen by default.

You can use in Ruby 2.x. Just add this comment to the first line of your files.

 # frozen_string_literal: true 

The above comment at the top of the file changes the semantics of static string literals in the file. Static string literals will be frozen and will always return the same object. (The semantics of dynamic string literals does not change.)

This method has the following advantages:

There is no ugly f-suffix. No syntax error on old Ruby. We only need a line for each file.

Please read this topic for more information.

https://bugs.ruby-lang.org/issues/8976

+13
Aug 01 '18 at 13:18
source share

This improves application performance by not allocating new space for the same row, thereby saving time on garbage collection. How? when you freeze a string literal (string object), you tell Ruby so that none of your programs change the string literal (object).

A few obvious observations to keep in mind.

1. By freezing string literals, you do not allocate new memory space for this.

Example:

Without a magic comment , a new place is allocated for the same line (note the different identifiers of the object)

 def hello_id a = 'hello' a.object_id end puts hello_id #=> 70244568358640 puts hello_id #=> 70244568358500 

With a magical commentary , a ruby ​​makes room only once

 # frozen_string_literal: true def hello_id a = 'hello' a.object_id end puts hello_id #=> 70244568358640 puts hello_id #=> 70244568358640 



2. By freezing string literals, your program will throw an exception when you try to modify a string literal.

Example:

Without magic comment, you can change string literals.

 name = 'Johny' name << ' Cash' puts name #=> Johny Cash 

With a magic comment , an exception will be thrown when you modify string literals

 # frozen_string_literal: true name = 'john' name << ' cash' puts name #=> '<main>': can't modify frozen String (FrozenError) 

There is always something to learn and be flexible:

+3
Apr 29 '19 at 9:11
source share



All Articles