Spec-Zone.ru › Ruby 3

Комментарии к коду

В 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API