|
| 1 | +# コメント |
| 2 | + |
| 3 | + - [ref:line_comment] |
| 4 | + - [ref:embedded_document] |
| 5 | + - [ref:magic_comment] |
| 6 | + - [ref:encoding] |
| 7 | + - [ref:frozen_string_literal] |
| 8 | + - [ref:warn_indent] |
| 9 | +#@since 3.0 |
| 10 | + - [ref:shareable_constant_value] |
| 11 | +#@end |
| 12 | + |
| 13 | +Ruby のコメントには、`#` から行末までを対象とする行コメントと、 |
| 14 | +`=begin` から `=end` までの行を対象とする埋め込みドキュメントの |
| 15 | +2 種類があります(字句規則については [ref:d:spec/lexical#comment] も参照してください)。 |
| 16 | + |
| 17 | +また、ソースファイルの先頭に書かれた特定の形式のコメントは「マジックコメント」 |
| 18 | +と呼ばれ、通常のコメントとは違い、Ruby の処理系に対してエンコーディングの |
| 19 | +指定や文字列リテラルの扱いなどを伝える働きを持ちます。 |
| 20 | + |
| 21 | +### 行コメント {#line_comment} |
| 22 | + |
| 23 | +```ruby title="例" |
| 24 | +# これは行コメントです。 |
| 25 | +p 1 + 1 # 式の後ろに書いたコメントです。 |
| 26 | +``` |
| 27 | + |
| 28 | +`#` から行末まではコメントとみなされ、Ruby インタプリタからは無視されます。 |
| 29 | +ただし文字列リテラルの中の `#` や、`?#` という文字リテラルの `#` は |
| 30 | +コメントの開始とはみなされません。 |
| 31 | + |
| 32 | +### 埋め込みドキュメント(`=begin` 〜 `=end`) {#embedded_document} |
| 33 | + |
| 34 | +```ruby title="例" |
| 35 | +=begin |
| 36 | +ここから =end のある行までは |
| 37 | +複数行にわたるコメント(埋め込みドキュメント)になります。 |
| 38 | +=end |
| 39 | +puts "hello" |
| 40 | +``` |
| 41 | + |
| 42 | +行頭(桁 0、インデントなし)から始まる `=begin` の行から、同じく行頭から |
| 43 | +始まる `=end` の行までの間はまとめてコメントとして扱われ、Ruby インタプリ |
| 44 | +タからは無視されます。`=begin` と `=end` はどちらもインデントすると |
| 45 | +埋め込みドキュメントとして認識されず、構文エラーになります。 |
| 46 | + |
| 47 | +```text title="インデントすると構文エラーになる例" |
| 48 | +x = 1 |
| 49 | + =begin |
| 50 | + この =begin はインデントされているため |
| 51 | + 埋め込みドキュメントの開始として認識されません。 |
| 52 | + =end |
| 53 | +``` |
| 54 | + |
| 55 | +`=begin`・`=end` の行には、続けて自由な文字列を書くこともできます |
| 56 | +(その部分も無視されます)。 |
| 57 | + |
| 58 | +```ruby title="例" |
| 59 | +=begin タイトルなど自由に書けます |
| 60 | +本文 |
| 61 | +=end 任意の文字列 |
| 62 | +puts "hello" |
| 63 | +``` |
| 64 | + |
| 65 | +Ruby インタプリタは埋め込みドキュメントの中身の書式を規定しませんが、 |
| 66 | +慣習として RD 形式で書かれることが期待されています。 |
| 67 | + |
| 68 | +### マジックコメントとは {#magic_comment} |
| 69 | + |
| 70 | +マジックコメントとは、ソースファイルの先頭部分に書かれた特定の形式の |
| 71 | +コメントのことで、Ruby の処理系に対してそのファイルの解釈方法に関する |
| 72 | +指示を伝えるものです。通常のコメントと違い、書ける位置と書き方の形式が |
| 73 | +決まっています。 |
| 74 | + |
| 75 | + - マジックコメントが効果を持つのは、それが書かれたファイル自身に |
| 76 | + 対してだけです。`require`/`load` で読み込む他のファイルや、 |
| 77 | + `eval` で評価する文字列には影響しません。 |
| 78 | + - ソースコード(実際に実行されるコード)より前に書かれている必要が |
| 79 | + あります。一度でも実行コードが出現した後に書いても無視されます。 |
| 80 | + - ファイルの 1 行目が `#!` から始まる shebang 行 |
| 81 | + ([ref:d:spec/rubycmd#shebang]) である場合、マジックコメントは |
| 82 | + 2 行目以降から探されます。 |
| 83 | + |
| 84 | +現在 Ruby が認識するマジックコメントには以下のものがあります。 |
| 85 | + |
| 86 | + - エンコーディングの指定([ref:encoding]) |
| 87 | + - 文字列リテラルの凍結([ref:frozen_string_literal]) |
| 88 | + - インデント不整合の警告([ref:warn_indent]) |
| 89 | +#@since 3.0 |
| 90 | + - 定数の Ractor 共有可能化([ref:shareable_constant_value]) |
| 91 | +#@end |
| 92 | + |
| 93 | +このうち、エンコーディングの指定だけは特別扱いされていて、ファイルの |
| 94 | +1 行目(shebang がある場合は 2 行目)に厳密に書かれている必要があります。 |
| 95 | +空行や他のコメント行を挟んだ位置に書いても認識されません。 |
| 96 | + |
| 97 | +#@since 3.0 |
| 98 | +それ以外のマジックコメント(frozen_string_literal, warn_indent, |
| 99 | +shareable_constant_value)は、実行コードより前であれば、複数のコメント行 |
| 100 | +や空行、`=begin`〜`=end` を挟んだ後に書いても認識されます。 |
| 101 | +#@else |
| 102 | +それ以外のマジックコメント(frozen_string_literal, warn_indent)は、実行 |
| 103 | +コードより前であれば、複数のコメント行や空行、`=begin`〜`=end` を挟んだ |
| 104 | +後に書いても認識されます。 |
| 105 | +#@end |
| 106 | + |
| 107 | +```ruby title="例(frozen_string_literalは複数のコメント行の後でも認識される)" |
| 108 | +# ファイルの説明などの通常のコメント |
| 109 | +# 続きのコメント |
| 110 | + |
| 111 | +# frozen_string_literal: true |
| 112 | +p "abc".frozen? #=> true |
| 113 | +``` |
| 114 | + |
| 115 | +複数のマジックコメントを、emacs のモードライン形式でまとめて 1 行に |
| 116 | +書くこともできます。 |
| 117 | + |
| 118 | +```ruby title="例" |
| 119 | +# -*- coding: utf-8; frozen_string_literal: true -*- |
| 120 | +p __ENCODING__ #=> #<Encoding:UTF-8> |
| 121 | +p "abc".frozen? #=> true |
| 122 | +``` |
| 123 | + |
| 124 | +### エンコーディングの指定 {#encoding} |
| 125 | + |
| 126 | +```ruby title="例" |
| 127 | +# coding: euc-jp |
| 128 | +p __ENCODING__ #=> #<Encoding:EUC-JP> |
| 129 | +``` |
| 130 | + |
| 131 | +ソースファイルのエンコーディング(スクリプトエンコーディング)を指定 |
| 132 | +します。以下のいずれの書き方でも認識されます。 |
| 133 | + |
| 134 | +```text |
| 135 | +# encoding: euc-jp |
| 136 | +# coding: euc-jp |
| 137 | +# -*- coding: euc-jp -*- |
| 138 | +``` |
| 139 | + |
| 140 | +Ruby 2.0 以降、マジックコメントが無い場合のデフォルトのスクリプト |
| 141 | +エンコーディングは UTF-8 です(Ruby 1.9 では US-ASCII でした)。 |
| 142 | + |
| 143 | +マジックコメントが指定されなかった場合の決定規則(コマンドライン引数 |
| 144 | +や shebang との優先順位など)や、shebang 行がある場合の書き方など、 |
| 145 | +より詳しい内容については [ref:d:spec/m17n#magic_comment] を参照して |
| 146 | +ください。[c:Encoding] クラス、[m:Encoding.default_external] も |
| 147 | +参照してください。 |
| 148 | + |
| 149 | +### 文字列リテラルの凍結(`frozen_string_literal`) {#frozen_string_literal} |
| 150 | + |
| 151 | +```ruby title="例" |
| 152 | +# frozen_string_literal: true |
| 153 | + |
| 154 | +s = "abc" |
| 155 | +p s.frozen? #=> true |
| 156 | + |
| 157 | +begin |
| 158 | + s << "d" |
| 159 | +rescue => e |
| 160 | + p e.class #=> FrozenError |
| 161 | +end |
| 162 | +``` |
| 163 | + |
| 164 | +`true` を指定すると、そのファイル内の文字列リテラルから生成される |
| 165 | +[c:String] オブジェクトが、生成された時点であらかじめ freeze された |
| 166 | +状態になります。`false`(指定しなかった場合のデフォルト)では、この |
| 167 | +機能は無効です。 |
| 168 | + |
| 169 | +この設定はファイル単位で有効になります。`require`/`load` で読み込んだ |
| 170 | +他のファイルの文字列リテラルや、`eval` で評価した文字列リテラルには |
| 171 | +影響しません。 |
| 172 | + |
| 173 | +```ruby title="例(require先やevalには伝播しない)" |
| 174 | +# frozen_string_literal: true |
| 175 | +eval('p "abc".frozen?') #=> false |
| 176 | +``` |
| 177 | + |
| 178 | +freeze されていないコピーが必要な場合は [m:Object#dup] や単項演算子 |
| 179 | +`+`([m:String#+@])が、明示的に freeze したコピーが必要な場合は |
| 180 | +単項演算子 `-`([m:String#-@])が使えます。 |
| 181 | + |
| 182 | +### インデント不整合の警告(`warn_indent`) {#warn_indent} |
| 183 | + |
| 184 | +```ruby title="例" |
| 185 | +# warn_indent: true |
| 186 | + |
| 187 | +def foo |
| 188 | + if true |
| 189 | + puts "x" |
| 190 | + end # if に対して end のインデントの深さが揃っていない |
| 191 | +end |
| 192 | +``` |
| 193 | + |
| 194 | +```console |
| 195 | +$ ruby -w indent.rb |
| 196 | +indent.rb:6: warning: mismatched indentations at 'end' with 'if' at 4 |
| 197 | +``` |
| 198 | + |
| 199 | +`end` と、それに対応するキーワード(`if` など)とでインデントの深さが |
| 200 | +異なる場合に警告を出すかどうかを指定します。この警告自体はデフォルトで |
| 201 | +有効になっていますが、実際に表示されるのは `-w` オプションや `-W2` |
| 202 | +を指定して実行した場合(`$VERBOSE` が true の場合)に限られます。 |
| 203 | + |
| 204 | +`# warn_indent: false` と指定すると、`-w`/`-W2` を指定して実行した |
| 205 | +場合でもこの警告を抑制できます。意図的に特殊なインデントを使うコード |
| 206 | +(DSL やコード生成物など)で警告を消したい場合に使われます。 |
| 207 | + |
| 208 | +#@since 3.0 |
| 209 | +### 定数の Ractor 共有可能化(`shareable_constant_value`) {#shareable_constant_value} |
| 210 | + |
| 211 | +```ruby title="例" |
| 212 | +# shareable_constant_value: literal |
| 213 | + |
| 214 | +FOO = {a: 1, b: [1, 2, 3]} |
| 215 | +p Ractor.shareable?(FOO) #=> true |
| 216 | +p FOO.frozen? #=> true |
| 217 | +``` |
| 218 | + |
| 219 | +このマジックコメントより後にある定数への代入について、その値をどこまで |
| 220 | +自動的に [c:Ractor] で共有可能([m:Ractor.shareable?])にするかを指定します。 |
| 221 | +以下のいずれかを指定します。 |
| 222 | + |
| 223 | + - **`none`**(デフォルト): 何もしません。通常通りの代入を行います。 |
| 224 | + - **`literal`**: 代入される値がリテラルであり、かつその中身も再帰的に |
| 225 | + 共有可能な値だけからなる場合に、freeze して共有可能にします。 |
| 226 | + - **`experimental_everything`**: 代入される値がリテラルであるかに |
| 227 | + 関わらず、[m:Ractor.make_shareable] を使って共有可能にします |
| 228 | + (実験的機能)。 |
| 229 | + - **`experimental_copy`**: `experimental_everything` と同様ですが、 |
| 230 | + 共有可能でない値の場合、元のオブジェクトを直接 freeze するのでは |
| 231 | + なく、コピーしてから freeze して共有可能にします([m:Ractor.make_shareable] |
| 232 | + の `copy: true` に相当、実験的機能)。 |
| 233 | + |
| 234 | +```ruby title="例(experimental_copyは代入前にコピーを作る)" |
| 235 | +# shareable_constant_value: experimental_copy |
| 236 | + |
| 237 | +obj = Object.new |
| 238 | +FOO = obj |
| 239 | +p Ractor.shareable?(FOO) #=> true |
| 240 | +p FOO.equal?(obj) #=> false (コピーされている) |
| 241 | +``` |
| 242 | +#@end |
0 commit comments