[前][次][番号順一覧][スレッド一覧]

ruby-changes:64529

From: Marc-Andre <ko1@a...>
Date: Thu, 24 Dec 2020 01:51:22 +0900 (JST)
Subject: [ruby-changes:64529] 8feb40f49a (master): Document shareable_constant_value and other magic constants [doc]

https://git.ruby-lang.org/ruby.git/commit/?id=8feb40f49a

From 8feb40f49a5862ba1a42a5d8d9e228e1a8883a29 Mon Sep 17 00:00:00 2001
From: Marc-Andre Lafortune <github@m...>
Date: Wed, 16 Dec 2020 15:39:02 -0500
Subject: Document shareable_constant_value and other magic constants [doc]


diff --git a/NEWS.md b/NEWS.md
index f273b8b..f588a21 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -88,6 +88,10 @@ sufficient information, see the ChangeLog file or Redmine https://github.com/ruby/ruby/blob/trunk/NEWS.md#L88
 * Interpolated String literals are no longer frozen when
   `# frozen-string-literal: true` is used. [[Feature #17104]]
 
+* Magic comment `shareable_constant_value` added to freeze constants.
+  See {Magic Comments}[rdoc-ref:doc/syntax/comments.rdoc@Magic+Comments] for more details.
+  [[Feature #17273]]
+
 * A {static analysis}[rdoc-label:label-Static+analysis] foundation is
   introduced.
     * {RBS}[rdoc-label:label-RBS] is introduced. It is a type definition
@@ -757,6 +761,7 @@ end https://github.com/ruby/ruby/blob/trunk/NEWS.md#L761
 [Feature #17187]: https://bugs.ruby-lang.org/issues/17187
 [Bug #17221]:     https://bugs.ruby-lang.org/issues/17221
 [Feature #17260]: https://bugs.ruby-lang.org/issues/17260
+[Feature #17273]: https://bugs.ruby-lang.org/issues/17273
 [Feature #17303]: https://bugs.ruby-lang.org/issues/17303
 [Feature #17314]: https://bugs.ruby-lang.org/issues/17314
 [Feature #17322]: https://bugs.ruby-lang.org/issues/17322
diff --git a/doc/syntax/comments.rdoc b/doc/syntax/comments.rdoc
index a07dd41..e8e3fc3 100644
--- a/doc/syntax/comments.rdoc
+++ b/doc/syntax/comments.rdoc
@@ -35,3 +35,195 @@ syntax error: https://github.com/ruby/ruby/blob/trunk/doc/syntax/comments.rdoc#L35
     Will not work
     =end
   end
+
+== 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 start on the first line, or on the second line if
+the first line looks like <tt>#! shebang line</tt>.
+
+NOTE: Magic comments affect only the file in which they appear;
+other files are unaffected.
+
+  # frozen_string_literal: true
+
+  var = 'hello'
+  var.frozen? # => true
+
+=== Alternative syntax
+
+Magic comments may consist of a single directive (as in the example above).
+Alternatively, multiple directives may appear on the same line if separated by ";"
+and wrapped between "-*-" (See Emacs' {file variables}[https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html])
+
+  # emacs-compatible; -*- coding: big5; mode: ruby -*-
+
+  p 'hello'.frozen? # => true
+  p 'hello'.encoding # => #<Encoding:Big5>
+
+=== <code>encoding</code> Directive
+
+Indicates which string encoding should be used for string literals,
+regexp literals and `__ENCODING__`:
+
+  # encoding: big5
+
+  ''.encoding # => #<Encoding:Big5>
+
+Default encoding is UTF-8.
+
+It must appear in the first comment section of a file
+
+The word "coding" may be used instead of "encoding".
+
+=== <code>frozen_string_literal</code> Directive
+
+When appears in the top section of a file, indicates that string literals should be allocated once at parse time and frozen.
+
+  # frozen_string_literal: true
+
+  3.times do
+    p 'hello'.object_id # => prints same number
+  end
+  p 'world'.frozen? # => true
+
+The default is false; this can be changed with `--enable=frozen-string-literal`.
+Without the directive, or with <code># frozen_string_literal: false</code>,
+the example above would print 3 different numbers and "false".
+
+Starting in Ruby 3.0, string literals that are dynamic are not frozen nor reused:
+
+  # frozen_string_literal: true
+
+  p "Addition: #{2 + 2}".frozen? # => false
+
+It must appear in the first comment section of a file
+
+=== <code>warn_indent</code> Directive
+
+This directive can turn detection of bad indentation for statements that follow it:
+
+  def foo
+    end # => no warning
+
+  # warn_indent: true
+  def bar
+    end # => warning: mismatched indentations at 'end' with 'def' at 6
+
+Another way to get these warnings to show is by running Ruby with warnings (<code>ruby -w</code>). Using a directive to set this false will prevent these warnings to show.
+
+=== <code>shareable_constant_value</code> Directive
+
+Note: This directive is experimental in Ruby 3.0 and may change in future releases.
+
+This special directive helps to create constants that hold only immutable objects, or {Ractor-shareable}[rdoc-ref:Ractor@Shareable+and+unshareable+objects] constants.
+
+The directive can specify special treatment for values assigned to constants:
+
+* +none+: (default)
+* +literal+: literals are implicitly frozen, others must be Ractor-shareable
+* +experimental_everything+: all made shareable
+
+==== Mode +none+ (default)
+
+No special treatment in this mode (as in Ruby 2.x): no automatic freezing and no checks.
+
+It has always been a good idea to deep-freeze constants; Ractor makes this
+an even better idea as only the main ractor can access non-shareable constants:
+
+  # shareable_constant_value: none
+  A = {foo: []}
+  A.frozen? # => false
+  Ractor.new { puts A } # => can not access non-shareable objects by non-main Ractor.
+
+==== Mode +literal+
+
+In "literal" mode, constants assigned to literals will be deeply-frozen:
+
+  # shareable_constant_value: literal
+  X = [{foo: []}] # => same as [{foo: [].freeze}.freeze].freeze
+
+Other values must be shareable:
+
+  # shareable_constant_value: literal
+  X = Object.new # => cannot assign unshareable object to X
+
+Note that only literals directly assigned to constants, or recursively held in such literals will be frozen:
+
+  # 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.[]`)
+
+The method Module#const_set is not affected.
+
+==== Mode +experimental_everything+
+
+In this mode, all values assigned to constants are made shareable.
+
+  # shareable_constant_value: experimental_everything
+  FOO = Set.new[1, 2, {foo: []}] # => ok, since this is
+      # same as `Set.new[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
+
+This mode is "experimental", because it might be too error prone,
+for example by deep-freezing the constants of an exernal resource
+which could cause errors:
+
+  # shareable_constant_value: experimental_everything
+  FOO = SomeGem::Something::FOO
+  # => deep freezes the gem's constant!
+
+The method Module#const_set is not affected.
+
+==== Scope
+
+This directive can be used multiple times in the same file:
+
+  # 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::Error)
+
+  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
+
+The directive affect only subsequent constants and only for the current scope:
+
+  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
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]