Комментарии к коду
В 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, специальные «магические комментарии» содержат директивы, влияющие на интерпретацию кода.
Магические комментарии верхнего уровня должны начинаться на первой строке или на второй строке, если первая строка выглядит как #! shebang line.
ПРИМЕЧАНИЕ: Магические комментарии влияют только на файл, в котором они появляются; другие файлы не затрагиваются.
# frozen_string_literal: true var = 'hello' var.frozen? # => true
Альтернативный синтаксис
Магические комментарии могут состоять из одной директивы (как в примере выше). В качестве альтернативы, несколько директив могут появляться в одной строке, если они разделены «;» и заключены в «-*-» (см. переменные файлов Emacs).
# emacs-compatible; -*- coding: big5; mode: ruby -*- p 'hello'.frozen? # => true p 'hello'.encoding # => #<Encoding:Big5>
encoding Директива
Указывает, какой кодировку строк следует использовать для строковых литералов, литералов regexp и __ENCODING__:
# encoding: big5 ''.encoding # => #<Encoding:Big5>
По умолчанию используется UTF-8.
Он должен появляться в первом разделе комментариев файла.
Вместо «кодировка» можно использовать слово «кодировка».
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: глубокая копия и совместимость с Ractor
Режим 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
В режиме «литерал» константы, назначенные литералам, будут глубоко заморожены:
# shareable_constant_value: literal
X = [{foo: []}] # => same as [{foo: [].freeze}.freeze].freeze
Другие значения должны быть совместимыми с Ractor:
# 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
В этом режиме все значения, назначенные константам, делают совместимыми с Ractor.
# 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
В этом режиме все значения, назначенные константам, глубоко копируются и делаются совместимыми с Ractor. Это более безопасный режим, чем experimental_everything.
# shareable_constant_value: experimental_everything
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–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.