Rubyにもグローバル変数があり、これを使うとプログラムのどこからでも参照できます。しかしグローバル変数は極力使うべきではない、というのが今のプログラミングの常識です。もし利用する場合は、使い方に注意が必要です。
さらにRubyでは組み込み変数がグローバルと同じ書式を使い、グローバル変数と同じようにどこからでも参照できる組み込み変数もあります。今回はRubyにおけるグローバル変数と組み込み変数の使い方について紹介します。
グローバル変数とは
Rubyには参照できる範囲毎に4種類の変数があり、その中でどこからでも参照できる変数がグローバル変数です。なお、このようにプログラムのどこかでも参照できる変数は他のプログラミングにもありますが、特別な変数として使われており、これはRubyでも同じです。
プログラムのどこからでも参照できるグローバル変数には便利な反面、どこからでも書き換えできることからバグの原因となりやすい変数です。もし使う場合は他の変数と区別し、特別に扱わなければなりません。まずは一般的なグローバル変数の特徴について紹介します。
変数のスコープとバグの関係
プログラミングにおける良いコードの定義の1つに変数の少なさが挙げられます。変数が増えれば、それだけ処理が複雑になり、バグが発生しやすくなる、という訳です。
そのため今使われているプログラミング言語の多くでは変数を参照できる範囲が限定されており、Rubyでもローカル変数はメソッドやブロックの中でしか参照できません。これにより変数が原因の誤動作やバグを減らせます。
しかしプログラムのどこでも同じ値を使いたいケースがよくあります。そのような特別なケースでは
グローバル変数が使われます。プログラムのどこからでも参照できるグローバル変数は、プログラムの誤動作やバグの原因になりやすいことを理解したうえで利用する必要があります。
グローバル変数のメリットとデメリット
グローバル変数を利用するメリットは、同じ変数をプログラムのどこかでも使える点です。そのため組み込み用途など使えるメモリーが限定されているケースでは、同じ変数をいろいろな用途で使うためにグローバル変数が使われます。
しかし、プログラムの規模が大きくなるとそのような使い方はできません。ある処理でグローバル変数を使っている処理で呼び出した処理でそのグローバル変数を書き換えてしまえるので、誤動作やバグの原因になります。
そのため、Ruby on Railsが使えるWebシステムのような何人ものプログラマーが関わる開発では、グローバル変数を利用しないでプログラムを作るのが一般的です。
共通のデータはデータベースに
先ほどプログラムのどこからでも参照できるグローバル変数は利用が制限されると紹介しましたが、複数の処理で同じデータを参照したり保存するケースはよくあります。Ruby on Railsなどのフレームワークを利用するケースでは、共通で利用するデータの格納場所としてデータベースが利用されます。
データベースに格納されたデータは、変数のように手軽には利用できませんが、処理で必要となった時点でそのデータを読み出したり保存したりできます。このようにグローバル変数を使用しなくても、Webシステムなどを開発することは可能です。
Rubyの組み込み変数はグローバル変数
Rubyの組み込み変数は、グローバル変数と同じように変数名に「$」が付きます。そして組み込み変数のように、プログラムのどこからでも参照できる変数もあります。
ただし、だからと言って組み込み変数がグローバル変数の一種とは言えません。組み込み変数には、変数名に「$」が付いているにもかかわらず、参照範囲がローカル変数と同じ、という変数もあります。組み込み変数を使う場合は、参照範囲に注意してください。
組み込み変数の例
ライブラリをロードするための検索パス $LOAD_PATH、$:、$-I
現在実行中のRubyスクリプトの名前 $PROGRAM_NAME、$0
最後に成功した正規表現のパターンマッチでマッチした文字列 $&
最後に発生したExceptionオブジェクト $!
デフォルトの出力フィールド区切り文字列 $,
グローバル変数の基本
Rubyでは変数の種類に応じた変数名の付け方が決まっており、グローバル変数は変数名の1文字目が「$」で始まる変数名を使います。もし必要なら、下記の例のような独自のグローバル変数を設定できます。
グローバル変数の例
$global_value = "グローバル変数"
グローバル変数と組み込み変数の関係
先ほど紹介したとおり組み込み変数も「$PROGRAM_NAME」や「$LOAD_PATH」などの「$」で始まる変数です。
組み込み変数とは、Rubyの処理の中で特別な意味を与えられた定義済の変数です。Rubyのプログラムを実行した際に設定された組み込み変数や、直前の評価結果を格納した組み込み変数などがあります。
そしてRubyのコマンドオプションなど、Rubyのプログラムを実行した際に設定された値を格納した組み込み変数などはグローバル変数のようにプログラムの中ならどこからでも参照できます。一方直前の評価結果を格納した組み込み変数などはローカル変数と同じように、メソッド内またはブロック内でしか参照できません。
組み込み変数を利用する
プログラムの中でグローバル変数を新たに設定し、それを利用した処理を作ることは可能ですが、不具合の原因になりやすいので推奨されていません。
しかしグローバル変数と同じく「$」で始まる組み込み変数は、Rubyのプログラムでよく使われる変数です。次から代表的な組み込み変数の使い方について紹介します。
$LOAD_PATH
$LOAD_PATHは、requireでライブラリ検索するパスを格納している変数です。$LOAD_PATHの代わりに$:または$-Iで参照することもできます。そして、$LOAD_PATHはグローバル変数と同じでプログラムの中のどこからでも参照可能です。
なおライブラリ検索するパスは、Rubyをインストールした際に設定され、gemコマンドでライブラリを追加すると、$LOAD_PATHに設定されたパスのいずれかに格納されます。
また、ライブラリ検索するパスはRubyを実行する際に-Iオプションで設定でき、設定されたパスが$LOAD_PATHに格納されます。さらに、$LOAD_PATHを変更してシステム独自のライブラリをrequireで取り込むことも可能です。
$PROGRAM_NAME
$PROGRAM_NAMEは現在実行中のスクリプトの名前が格納されている組み込み変数です。$PROGRAM_NAMEの代わりに$0で参照することもできます。そして、この$PROGRAM_NAMEもグローバル変数と同じでプログラムの中のどこからでも参照可能です。
$&
Rubyでは文字列の検索などで簡単に正規表現を使えます。if構文にて正規表現でチェックした後に、マッチした文字列を次の処理で使うための変数が組み込み変数の$&です。$&は正規表現のパターンマッチで最後にマッチした文字列を格納しています。
なお$&は、$が付いているのでグローバル変数ですが組み込み変数のため特殊で、参照範囲はローカル変数と同じで、しかも読み取り専用です。そして、初期値は nilで、正規表現のパターンマッチに失敗した場合もnilが格納されます。
$!
Rubyで例外が発生したらExceptionオブジェクトが生成され、エラー内容やメッセージなどを参照できます。$!には最後に発生したExceptionオブジェクトの参照に使われる組み込み変数です。
$!も変数に$が付いているのでグローバル変数ですが組み込み変数のために特殊で、参照範囲はローカル変数と同じで、しかも読み取り専用です。
Rubyのコマンドオプションの値
Rubyをコマンドラインから実行する際、多くのオプションを指定できます。その中にはsplitメソッドのデフォルトの区切り文字やgetsメソッドの区切り文字など、デフォルトで省略した場合に使われる文字を指定できます。そのようなRubyの標準メソッドの処理で使われるデフォルトの文字コードが組み込み変数に格納されています。
そしてそれらの組み込み変数を変更すれば、Rubyのオプションで指定する代わりにデフォルトの文字コードを変更することが可能です。
区切り文字を格納した組み込み変数
$, デフォルトの出力フィールド区切り文字列
$-0 入力レコード区切りを表す文字列
$-F ing#split で引数を省略した場合の区切り文字
ほかにもRubyの実行に関する組み込み変数があるので、必要に応じて利用してください。
まとめ
これまで解説したようにRubyではスクリプトのどこからでも参照できるグローバル変数が使えます。そして、グローバル変数を使う場合は、変数名に「$」を付けます。ただし、グローバル変数は不具合の原因になりやすいので使い方に注意が必要です。
なお、Rubyの組み込み変数も「$」で始まります。ただし組み込み変数は「$」がついているからとグローバル変数と同じようにどこからでも参照できる訳ではありません。どこからでも参照できる組み込み変数もありますが、普通の変数のようにメソッドやブロックの中でしか参照できない変数もあります。組み込み変数を利用する場合は参照範囲に注意してください。