Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Ruby: Kernelの特殊変数を$記号を使わずに書く

更新情報

  • 2017/01/31: 初版公開
  • 2023/06/01: Ruby 3.2に沿って更新

こんにちは、hachi8833です。

Rubyスタイルガイドを読む: 文法(6)で以下のスタイルを扱いました。

Perl由来の特殊変数($:とか$;とか)は極力避けること

読みやすさのためにも$で始まる特殊変数は置き換えたいのですが、手頃な置き換え表がないので自分で作ってみました。

追記

特殊変数に英語名を追加するEnglishという標準ライブラリがあることを教えていただきましたので、この記事に反映しました。ありがとうございます!

組み込み変数について

まずはRubyの組み込み変数についてリファレンスを確認しました。

`$'で始まる変数はグローバル変数で、プログラムのどこからでも参照できます(その分、利用には注意が必要です)。 グローバル変数には宣言は必要ありません。初期化されていないグローバル変数を参照した時の値はnilです。
グローバル変数にはRuby処理系によって特殊な意味を与えられているものがあります。これらを組み込み変数と呼びます。
組み込み変数は文法解析上はグローバル変数として扱われます。しかし、実際のスコープは必ずしもグローバルとは限りません
Rubyリファレンス: 組み込み変数より

メモ


Ruby 3.2ドキュメント: Kernelの特殊変数より

  • require 'english'すると使える英名の後ろには「●」をつけています。
  • よく使いそうな順にグループ化しました。
  • 「初期値」は、該当する場合のみ記載します。
  • 現在使われてない変数($KCODEなど)や非推奨変数($=$IGNORECASEなど)は含めていません
  • リンクのtooltipに表示される読みはGoogle検索しやすくするためのものであり、正式な読みとは限りません。

🔗 正規表現関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$~ 最後のマッチのオブジェクト
MatchData、nil)
ローカルスコープかつスレッドローカル Regexp#last_match
$LAST_MATCH_INFO
$& 最後にマッチした文字列
String、nil)
ローカルスコープかつスレッドローカル
読み取り専用
Regexp#last_match[0]
$MATCH
$` マッチ部分より前の文字列
String、nil)
ローカルスコープかつスレッドローカル
読み取り専用
Regexp#last_match.pre_match
$PREMATCH
$' マッチ部分より後ろの文字列
String、nil)
ローカルスコープかつスレッドローカル
読み取り専用
Regexp#last_match.post_match
$POSTMATCH
$1...$11 マッチしたn番目のかっこに対応する文字列
String、nil)
ローカルスコープかつスレッドローカル、読み取り専用 Regexp.last_match[1]
$+ マッチした最後のかっこに対応する文字列
String、nil)
ローカルスコープかつスレッドローカル $LAST_PAREN_MATCH

🔗 デリミタ関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$;または$-F String#splitのデフォルト区切り文字列(String、nil)
文字列だが必ず正規表現にすること
$-FはRubyの起動オプション-Fで与える
グローバル $FIELD_SEPARATOR

🔗 入力関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$* Rubyスクリプトに与えられた引数の配列([String] グローバル Object::ARGV
$< すべての引数または標準入力で構成される仮想ファイル(IO) グローバル、読み取り専用 Object::ARGF
$DEFAULT_INPUT
$. 最後に読み込んだ行の行番号(Integer、0) グローバル IO#lineno(マルチスレッドでは特に)
$INPUT_LINE_NUMBER
$_ Kernel.#getsKernel.#readlineで最後に読み込んだ行の内容(String、nil) ローカルスコープかつスレッドローカル $LAST_READ_LINE

注釈

Ruby 2.4以前の$.Fixnumクラスとなっていましたが、FixnumはRuby 2.4で非推奨になりました。以後はRuby 2.4以前のドキュメントでもIntegerと表示されます。

🔗 出力関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$> 標準出力に何を使うかの指定(ObjectObject::STDOUT グローバル $stdout
$DEFAULT_OUTPUT
$, デフォルトの出力フィールド区切り文字列(String、nil)
Array#joinKernel.#printで使われる
グローバル $OFS
$\ Kernel.#printの最後に出力する区切り文字列(String、nil) グローバル $ORS

🔗 環境関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$0 実行中のRubyスクリプト名(String グローバル $PROGRAM_NAME
$" Kernel.#requireでロードされたファイル名の配列([String] グローバル $LOADED_FEATURES
$/または$-0 Kernel.#getsなどの入力区切り文字(String、nil)
デフォルトは\n
グローバル $INPUT_RECORD_SEPARATOR
$:または$-I Rubyライブラリのロードパスの配列([String]
$-IはRubyの起動オプション-Iで与える
グローバル $LOAD_PATH

🔗 プロセス関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$$ 現在実行中のプロセスID グローバル Process#id
$PID
$? スレッドで最後に終了した子プロセスのステータス(Process::Status、nil) スレッドローカル
読み取り専用
$CHILD_STATUS

🔗 警告関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$-W 現在の警告オプション(nil/false/true グローバル $VERBOSE
$-v 現在の冗長性オプション
Rubyの起動オプション-vで与えた値
グローバル $VERBOSE
$-w 現在の警告オプション
Rubyの起動オプション-wで与えた値
グローバル $VERBOSE

nilfalseで意味が異なっているのがドキドキします。

🔗 例外・デバッグ関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$! 発生した例外のオブジェクト(Exception、nil) スレッドローカル(nil)
読み取り専用
$ERROR_INFO
$@ 例外のバックトレースの配列([String]、nil) スレッドローカル $ERROR_POSITION
$-d デバッグモード(true/false
Rubyの起動オプション-dで与える
グローバル $DEBUG

🔗 その他起動オプションのフラグ関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$-a Rubyの「オートスプリットモード」の状態(true/false グローバル なし
$-i Rubyの起動オプション-iで与えた値 グローバル なし
$-l Rubyの起動オプション-lで与えた値 グローバル なし
$-p Rubyの起動オプション-pで与えた値 グローバル なし

最後に

よく言われていることではありますが、こうしてまとめてみるとRubyの$付き特殊変数にほとんど秩序がないことを痛感しました。対応する同等の英文字変数やメソッドもあるとは限りませんし、Rubyのバージョンが変わったときに割りと影響を受けやすいようにも思えましたが、Ruby 3.2.0の時点では特殊変数のリストに変更は見当たりませんでした。

関連記事

Rubyスタイルガイドを読む: 文法(6)演算子など


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。