Это rspec binstub в моем каталоге проекта.

#!/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")

Для чего это нужно?

# frozen_string_literal: true

Ответы (3)

# frozen_string_literal: true - это волшебный комментарий, впервые поддерживаемый в Ruby 2.3, который сообщает Ruby, что все строковые литералы в файле неявно заморожены, как если бы # freeze был вызван к каждому из них. То есть, если строковый литерал определен в файле с этим комментарием, и вы вызываете метод для этой строки, который его изменяет, например <<, вы получите RuntimeError: can ' t изменить замороженную строку.

Комментарий должен быть в первой строке файла.

В Ruby 2.3 вы можете использовать этот волшебный комментарий для подготовки к замороженным строковым литералам, используемым по умолчанию в Ruby 3.

В Ruby 2.3 запускайте с флагом - enable = frozen-string-literal, , а в Ruby 3, строковые литералы замораживаются во всех файлах. Вы можете переопределить глобальную настройку с помощью # frozen_string_literal: false.

Если вы хотите, чтобы строковый литерал был изменяемым независимо от глобальных настроек или настроек для каждого файла, вы можете префикс унарного оператора + (будьте осторожны с приоритетом операторов) или вызовите . dup на нем:

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

Вы также можете заморозить изменяемую (незамороженную) строку с помощью унарных -.

В Ruby 3.0. Матц (создатель Ruby) решил по умолчанию заморозить все строковые литералы.

EDIT 2019: он решил отказаться от идеи сделать замороженные строковые литералы по умолчанию для Ruby 3.0 (источник: https://bugs.ruby-lang.org/issues/11473#note-53)


Вы можете использовать в Ruby 2.x. Просто добавьте этот комментарий в первую строку ваших файлов.

# frozen_string_literal: true

Приведенный выше комментарий в верхней части файла изменяет семантику статической строки литералы в файле. Статические строковые литералы будут заморожены и всегда возвращает один и тот же объект. (Семантика динамических строковых литералов не меняется.)

Этот способ имеет следующие преимущества:

Никакого уродливого f-суффикса. Нет синтаксической ошибки на более старом Ruby. Нам нужна только линия для каждого файла.

Пожалуйста, прочтите эту тему для получения дополнительной информации.

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

Это улучшает производительность приложения, поскольку не выделяет новое пространство для той же строки, что также экономит время на рутинную сборку мусора. Как? когда вы замораживаете строковый литерал (строковый объект), вы говорите Ruby, чтобы ни одна из ваших программ не изменяла строковый литерал (объект).

Следует иметь в виду некоторые очевидные наблюдения.

1. Замораживая строковые литералы, вы не выделяете для него новое место в памяти.

Пример:

Без магического комментария выделяет новое место для той же строки (Обратите внимание на различные напечатанные идентификаторы объектов)

def hello_id
  a = 'hello'
  a.object_id
end

puts hello_id   #=> 70244568358640
puts hello_id   #=> 70244568358500

С магическим комментариемрубин выделяет пространство только один раз

# frozen_string_literal: true

def hello_id
  a = 'hello'
  a.object_id
end

puts hello_id   #=> 70244568358640
puts hello_id   #=> 70244568358640

2. Замораживая строковые литералы, ваша программа вызовет исключение при попытке изменить строковый литерал.

Пример:

Без магического комментария, вы можете изменять строковые литералы.

name = 'Johny'
name << ' Cash'

puts name     #=> Johny Cash

С магическим комментарием, при изменении строковых литералов

возникает исключение.

# frozen_string_literal: true

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

Всегда есть чему учиться и проявлять гибкость:

2022 WebDevInsider