Комментарии в коде
В Ruby есть два типа комментариев: однострочные и блочные.
Однострочные комментарии начинаются с символа # и продолжаются до конца строки:
# On a separate line class Foo # or at the end of the line # can be indented def bar end end
Блочные комментарии начинаются с =begin и заканчиваются =end. Каждый из них должен начинаться с новой строки.
=begin This is commented out =end class Foo end =begin some_tag this works, too =end
=begin и =end нельзя делать отступом, поэтому следующий код вызовет синтаксическую ошибку:
class Foo =begin Will not work =end end
Магические комментарии
Хотя Ruby обычно игнорирует комментарии, специальные «магические комментарии» содержат директивы, влияющие на интерпретацию кода.
Магические комментарии верхнего уровня должны находиться в первом разделе комментариев файла.
ПРИМЕЧАНИЕ: Магические комментарии влияют только на файл, в котором они находятся; на другие файлы они не распространяются.
# frozen_string_literal: true var = 'hello' var.frozen? # => true
Альтернативный синтаксис
Магический комментарий может состоять из одной директивы (как в примере выше). Также в одной строке могут быть указаны несколько директив, если разделить их символом «;» и заключить между «-*-» (см. переменные файла в Emacs).
# emacs-compatible; -*- coding: big5; mode: ruby; frozen_string_literal: true -*- p 'hello'.frozen? # => true p 'hello'.encoding # => #<Encoding:Big5>
encoding Директива
Указывает, какую кодировку строк следует использовать для строковых литералов, литералов regexp и __ENCODING__:
# encoding: big5 ''.encoding # => #<Encoding:Big5>
По умолчанию используется кодировка UTF-8.
Магические комментарии верхнего уровня должны начинаться в первой строке или во второй строке, если первая строка выглядит как строка шебанга !.
Вместо «encoding» можно использовать слово «coding».
frozen_string_literal Директива
Указывает, что строковые литералы должны создаваться один раз во время синтаксического разбора и замораживаться.
# frozen_string_literal: true 3.times do p 'hello'.object_id # => prints same number end p 'world'.frozen? # => true
По умолчанию установлено значение false; его можно изменить с помощью --enable=frozen-string-literal. Без этой директивы или при frozen_string_literal: false приведённый выше пример вывел бы 3 разных числа и «false».
Начиная с Ruby 3.0 динамические строковые литералы не замораживаются и не используются повторно:
# frozen_string_literal: true
p "Addition: #{2 + 2}".frozen? # => false
Директива должна находиться в первом разделе комментариев файла.
warn_indent Директива
Эта директива включает обнаружение неправильных отступов в последующих инструкциях:
def foo end # => no warning # warn_indent: true def bar end # => warning: mismatched indentations at 'end' with 'def' at 6
Ещё один способ увидеть эти предупреждения — запустить Ruby с предупреждениями (ruby -w). Если с помощью директивы установить значение false, эти предупреждения отображаться не будут.
shareable_constant_value Директива
Примечание: эта директива является экспериментальной в Ruby 3.0 и может измениться в будущих выпусках.
Эта специальная директива помогает создавать константы, содержащие только неизменяемые объекты, или константы, доступные для совместного использования в Ractor.
Директива может задавать особую обработку значений, присваиваемых константам:
-
none: (по умолчанию) -
literal: литералы неявно замораживаются, остальные значения должны быть доступны для совместного использования в Ractor -
experimental_everything: все значения становятся доступными для совместного использования -
experimental_copy: глубокое копирование и обеспечение доступности для совместного использования
Режим none (по умолчанию)
В этом режиме особая обработка не применяется (как в Ruby 2.x): автоматического замораживания и проверок нет.
Глубоко замораживать константы всегда было хорошей идеей; Ractor делает её ещё более разумной, поскольку только главный ractor может обращаться к константам, недоступным для совместного использования:
# shareable_constant_value: none
A = {foo: []}
A.frozen? # => false
Ractor.new { puts A } # => can not access non-shareable objects by non-main Ractor.
Режим literal
В режиме «literal» константы, которым присвоены литералы, глубоко замораживаются:
# shareable_constant_value: literal
X = [{foo: []}] # => same as [{foo: [].freeze}.freeze].freeze
Другие значения должны быть доступны для совместного использования:
# shareable_constant_value: literal X = Object.new # => cannot assign unshareable object to X
Обратите внимание: замораживаются только литералы, непосредственно присвоенные константам, или литералы, рекурсивно содержащиеся в таких литералах:
# shareable_constant_value: literal
var = [{foo: []}]
var.frozen? # => false (assignment was made to local variable)
X = var # => cannot assign unshareable object to X
X = Set[1, 2, {foo: []}].freeze # => cannot assign unshareable object to X
# (`Set[...]` is not a literal and
# `{foo: []}` is an argument to `Set.[]`)
На метод Module#const_set это не влияет.
Режим experimental_everything
В этом режиме все значения, присвоенные константам, становятся доступными для совместного использования.
# shareable_constant_value: experimental_everything
FOO = Set[1, 2, {foo: []}]
# same as FOO = Ractor.make_sharable(...)
# OR same as `FOO = Set[1, 2, {foo: [].freeze}.freeze].freeze`
var = [{foo: []}]
var.frozen? # => false (assignment was made to local variable)
X = var # => calls `Ractor.make_shareable(var)`
var.frozen? # => true
Этот режим является «экспериментальным», поскольку может приводить к ошибкам, например, из-за глубокого замораживания констант внешнего ресурса:
# shareable_constant_value: experimental_everything FOO = SomeGem::Something::FOO # => deep freezes the gem's constant!
До выхода Ruby 3.1 этот режим будет пересмотрен: либо будет разрешено использовать «everything», либо режим будет удалён.
На метод Module#const_set это не влияет.
Режим experimental_copy
В этом режиме все значения, присвоенные константам, глубоко копируются и становятся доступными для совместного использования. Этот режим безопаснее, чем experimental_everything.
# shareable_constant_value: experimental_copy
var = [{foo: []}]
var.frozen? # => false (assignment was made to local variable)
X = var # => calls `Ractor.make_shareable(var, copy: true)`
var.frozen? # => false
Ractor.shareable?(X) #=> true
var.object_id == X.object_id #=> false
Этот режим является «экспериментальным» и не был тщательно обсуждён. До выхода Ruby 3.1 этот режим будет пересмотрен: либо будет разрешено использовать «copy», либо режим будет удалён.
На метод Module#const_set это не влияет.
Область действия
Эту директиву можно использовать в одном файле несколько раз:
# shareable_constant_value: none
A = {foo: []}
A.frozen? # => false
Ractor.new { puts A } # => can not access non-shareable objects by non-main Ractor.
# shareable_constant_value: literal
B = {foo: []}
B.frozen? # => true
B[:foo].frozen? # => true
C = [Object.new] # => cannot assign unshareable object to C (Ractor::IsolationError)
D = [Object.new.freeze]
D.frozen? # => true
# shareable_constant_value: experimental_everything
E = Set[1, 2, Object.new]
E.frozen? # => true
E.all(&:frozen?) # => true
Директива влияет только на последующие константы и только в текущей области действия:
module Mod
# shareable_constant_value: literal
A = [1, 2, 3]
module Sub
B = [4, 5]
end
end
C = [4, 5]
module Mod
D = [6]
end
p Mod::A.frozen?, Mod::Sub::B.frozen? # => true, true
p C.frozen?, Mod::D.frozen? # => false, false
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.