Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: What does the comment "frozen_string_literal: true" do?

This is the 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 is this intended to do?

# frozen_string_literal: true 
like image 229
messanjah Avatar asked Jun 13 '16 21:06

messanjah


People also ask

What does Frozen_string_literal true do?

Starting with Ruby 2.3, if you add the magic comment # frozen_string_literal: true to the file, the string literal for greeting is then automatically frozen (meaning it can't be modified). This means that if name is present and we try to personalize the greeting, a runtime error will be raised.

What is a frozen string?

This means that any string literal within your code is frozen and cannot be modified. As an added bonus, identical string literals in multiple locations are the same object (and for what it's worth, this is how symbols already behave), so the memory profile of your app is potentially reduced.

How do I fix missing frozen string literal comment?

The property can be found here: FrozenStringLiteral. This change just silences the warning. The linked page describes the right solution: Add the frozen_string_literal comment to the top of files to help transition to frozen string literals by default. .

What are magic comments in Ruby?

Magic Comments. While comments are typically ignored by Ruby, special “magic comments” contain directives that affect how the code is interpreted. Top-level magic comments must appear in the first comment section of a file. NOTE: Magic comments affect only the file in which they appear; other files are unaffected.


2 Answers

# frozen_string_literal: true is a magic comment, supported for the first time in Ruby 2.3, that tells Ruby that all string literals in the file are implicitly frozen, as if #freeze had been called on each of them. That is, if a string literal is defined in a file with this comment, and you call a method on that string which modifies it, such as <<, you'll get RuntimeError: can't modify frozen String.

The comment must be on the first line of the file.

In Ruby 2.3, you can use this magic comment to prepare for frozen string literals being the default in Ruby 3.

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

If you want a string literal to be mutable regardless of the global or per-file setting, you can prefix it with the unary + operator (being careful with operator precedence) or call .dup on it:

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

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

like image 101
Dave Schweisguth Avatar answered Oct 11 '22 05:10

Dave Schweisguth


It improves application performance by not allocating new space for the same string, thereby also saving time for garbage collection chores. How? when you freeze a string literal(string object), you're telling Ruby to not let any of your programs modify the string literal (object).

Some obvious observations to keep in mind.

1. By freezing string literals, you're not allocating new memory space for it.

Example:

Without magic comment allocates new space for the same string (Observe the different object IDs printed)

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

With magic comment, ruby allocates space 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 raise an exception when trying to modify the string literal.

Example:

Without magic comment, you can modify the string literals.

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

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

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

There's always more to learn and be flexible:

  • https://bugs.ruby-lang.org/issues/8976
  • https://www.mikeperham.com/2018/02/28/ruby-optimization-with-one-magic-comment/
like image 23
Tenzin Chemi Avatar answered Oct 11 '22 04:10

Tenzin Chemi