[Ruby] Kernelの特殊変数をできるだけ$記号なしで書いてみる

こんにちは、hachi8833です。

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

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

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

追記

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

組み込み変数について

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

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

メモ

  • Ruby 2.4.0の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$2、… マッチした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

$.はリンク先ではFixnumクラスと書かれていましたが、Ruby 2.4ではFixnumは非推奨になったので、実際はIntegerでした。

出力関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$> 標準出力に何を使うかの指定(Object、Object::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

プロセス関連

$を使う変数 内容(クラス、初期値) 特性 同等の英文字変数など
$* Rubyスクリプトに与えられた引数の配列([String]) グローバル Object::ARGV
$$ 現在実行中のプロセス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 デバッグモード(Bool)
Rubyの起動オプション-dで与える
グローバル $DEBUG

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

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

最後に

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

関連記事

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ