2016-11-02
特殊変数の一覧
- Perl ›
- 特殊変数
Perlの「特殊変数」の一覧です。「特殊変数」とは、Perlであらかじめ定義されているグローバル変数のことです。変数名によって、その用途が特定されています。
必ず覚えておきたい特殊変数
これだけは必ず覚えておきたいという特殊変数から紹介します。
「@ARGV」- コマンドライン引数
「@ARGV」には、コマンドライン引数が代入されています。
@ARGV
コマンドライン引数の詳細については、「Perlで「コマンドライン引数」を処理する」をご覧ください。
「@_」 - サブルーチンの引数
「@_」には、サブルーチンの引数が代入されてきます。
@_
サブルーチンにおける引数の扱い方については「サブルーチンを作成する方法 」をご覧ください。
「$1, $2, $3, ...」 - 正規表現でキャプチャされた文字列
「$1」「$2」「$3」には、正規表現でキャプチャされた文字列が代入されます。
$1; $2; $3;
正規表現における文字列のキャプチャについては「実践で役立つPerl正規表現 完全解説」をご覧ください。
「$_」 - デフォルト引数
「$_」は関数の引数を省略したときに想定される引数で「デフォルト引数」と呼ばれます。自分でデフォルト引数を利用することは、可読性のことを考えると控えたほうがよいですが、標準関数には、デフォルト引数を利用するものがあるので、いくつか覚えておく必要があります。
最低限、map関数、grep関数、後置のforで「$_」が使われることが多いので覚えておきましょう。
map関数
map { $_ => 1} @elements
grep関数
grep { $_ eq 'foo' } @elements
後置のfor
$_ for @elements;
覚えておくと便利な特殊変数
必須ではないけれど、しばしばソースコードに登場するし、覚えておくと便利なことがあるという特殊変数を紹介します。
%ENV - 環境変数の取得と設定
環境変数には%ENVという特殊変数でアクセスできます。
%ENV
環境変数名が、キーになっており $ENV{'env_name'} で値を参照できます。環境変数とは、OSが持つ変数のようなものです。環境変数は、OSがプロセスを起動したときに、プロセス空間のメモリ上にコピーされます。OSの環境変数は、プロセスからは、変更できません。
環境変数は、自由に設定変更できますが、そのプロセスでのみで有効です。あるプロセスが、子プロセスを起動したときは、OSが、プロセスを起動したときのように、環境変数がコピーされます。
$0 - プログラム名を取得する
プログラム名を取得するには特殊変数「$0」を使用します。
$0;
プログラムを起動したときの名前を取得します。つまり、絶対パスでプログラムを指定すれば、絶対パス名が、カレントディレクトリから、相対パスで指定した場合は、相対パス名で、プログラム名を取得できます。
@INC - モジュールの検索パスのリスト
モジュールの検索パスは@INCという特殊変数に代入されています。
@INC
モジュールの検索パスとは、Perlが、モジュールを読み込むために、検索するディレクトリのことです。@INC に、含まれないディレクトリに置かれたモジュールは、読み込むことができません。
use lib を使って、モジュールの検索パスを追加する
use lib './lib';
use lib モジュールを使うことで、コンパイル時に、@INC に、検索パスを追加できます。
@INC の先頭に直接、モジュールの検索パスを追加する
unshift @INC, './lib2';
unshift で、直接先頭に、追加します。このやり方より、use lib を用いるほうがよいです。use lib を使う利点は、コンパイル時に、検索パスが追加されることと、可読性が高まること、アーキテクチャに応じたパスも追加されることです。
%INC - 読み込まれているモジュールを調べる
読み込まれているモジュールを調べるには%INCという変数を見ます。
%INC
%INC ハッシュは、モジュール名とモジュールのファイル名の組み合わせが、代入されています。モジュール名と、実際にどのファイルをインポートしたのかがわかります。
モジュールの検索パスが格納されている、 @INC とは何の関係もありません。@INC と %INC はまったく別の変数です。モジュール名だけを知りたい場合は、keys 関数で、キーだけを取り出してあげます。
$^O - OS名を取得する
OS名を取得するには$^Oという特殊変数を使用します。
$^O
$^O の値とOSの種類
各OSにおける「$^O」の値をまとめました。
| $^Oの値 | 説明とリンク |
| MacOS | MacOS |
| MSWin32 | Windows 全般 |
| os2 | OS/2 |
| VMS | VMS |
| epoc | EPOC OS (たぶん) |
| NetWare | NetWare |
| symbian | Symbian OS |
| dos | MS-DOS |
| cygwin | cygwin |
| linux | Linux |
| freebsd | FreeBSD |
| solaris | Solaris |
| Unix ( 違うかも ) | Unix |
| darwin | Mac OS X |
| CentOS | Linux |
その他の特殊変数
$$ - プロセスIDを取得する
プロセスIDを取得するには特殊変数「$$」を使用します。
$$
プロセスIDとは、OSがプロセスを一意に識別するために、プロセス起動時に割り当てる識別子のことです。
$^T - プロセスの開始時刻を取得する
プロセスの開始時刻を取得するには特殊変数「$^T」を使用します。
$^T
時刻は、エポック秒(1970年1月1日0時0分0秒からの秒数) で取得されます。
$? - 子プロセスの終了ステータス
waitで子プロセスの終了を待った]場合は、$?に子プロセスの終了ステータスを含めた複数の値が格納されます。またsystem関数を使って子プロセスを実行した場合にも$?が設定されます。
子プロセスの終了ステータス
$?の解釈の方法はやや複雑です。$?には16ビットの値が設定されます。上位8ビットに子プロセスの終了ステータスが設定されます。下位8ビットの8ビット目には、コアダンプが生成されたかどうかを表します。下位8ビットの7ビット目までは、もしあればプロセスを終了させたシグナルの番号を表します。
|----------------------+----+------------------|
| 8 | 1 | 7 |
|----------------------+----+------------------|
| | |
終了ステータス コアダンプの 子プロセスを終了させたシグナル
発生
ですので、終了ステータスを取得するためには、$?を8ビット右にシフトさせる必要があります。
# 終了ステータスの取得 my $exit_value = $? >> 8;
コアダンプが発生したかどうかを見るには
# コアダンプが発生したかどうか my $dumped_core = $? & 128;
とします。128は2進数になおすと 10000000 ですので、ビット積をとると8ビット目以外が0になります。子プロセスを終了させたシグナル番号を見るには
# 子プロセスを終了させたシグナル番号 my $signal_num = $? & 127;
とします。127は2進数で、01111111 ですので、ビット積をとると下位7ビットが取得できます。
子プロセスが終了したかどうかを調べる
wait関数はCHLDシグナルが発生すると制御を戻します。つまり、子プロセスが終了したときだけではなく、子プロセスが停止したり、再開したりした場合にも制御が戻るということです。
子プロセスが確実に終了したかどうかを調べるには、WIFEXITED 関数を使用します。
use POSIX q(:sys_wait_h); my $is_finished = WIFEXITED($?);
子プロセスの終了ステータスを見るサンプル
子プロセスの中でdieを呼んだので終了ステータスは255になります。親プロセスがこのステータスを取得できているのがわかると思います。
use strict; use warnings; use POSIX qw(:sys_wait_h); my $pid = fork; die "Cannot fork: $!" unless defined $pid; if ($pid) { # 子プロセスの終了を待機する。 wait; print "親プロセス( 子プロセスID: $pid )\n\n"; my $exit_value = $? >> 8; my $dumped_core = $? & 128; my $signal_num = $? & 127; my $is_finished = WIFEXITED( $? ); print "子プロセスの終了コード: $exit_value\n"; print "コアダンプが発生したかどうか : $dumped_core\n"; print "子プロセスを終了させたシグナル : $signal_num\n"; print "子プロセスが終了したかどうか : $is_finished\n"; } else { # 子プロセスで2秒待つ sleep 2; print "子プロセス\n"; die; }
実行結果は
子プロセス Died at c.pl line 29. 親プロセス(子プロセスID: 13830) 子プロセスの終了コード: 255 コアダンプが発生したかどうか : 0 子プロセスを終了させたシグナル : 0 子プロセスが終了したかどうか : 1
のようになります。
すべての特殊変数の一覧
特殊変数の一覧を以下にまとめておきます。詳細についてはPerlの公式ドキュメント「perlvar」をご覧ください。
| 特殊変数 | 意味 |
|---|---|
| $_ | デフォルト引数 |
| @_ | サブルーチンの引数 |
| $" | 配列がダブルクォートで変数展開された場合のセパレーター |
| $$ | プロセスID |
| $0 | 実行されているプログラムの名前 |
| $( | プロセスの実グループID |
| $) | プロセスの実行グループID |
| $< | プロセスの実ユーザーID |
| $> | プロセスの実行ユーザーID |
| $; | 多次元配列のエミュレーションのための添え字の区切り文字 |
| $a, $b | sort関数で使う変数 |
| %ENV | 環境変数 |
| $^F | ファイル記述子の最大値 |
| @F | 自動スプリットモードが有効の場合、それぞれの行のフィールドを含む |
| @INC | ライブラリの読み込みパスのリスト |
| %INC | インクルードされたファイルの名前の一覧 |
| $^I | 置き換え変数の拡張子 |
| $^M | メモリが足りなくなった場合にトラップするか |
| $^O | オペレーティングシステムの名前 |
| %SIG | シグナルハンドラ |
| $^T | プログラムを開始した時刻 |
| $^V | Perlのバージョン情報 |
| $^X | 実行されたときの名前 |
| $1, $2, $3 | 正規表現でキャプチャされた文字列 |
| $& | 最後に成功したパターンマッチでマッチした文字列 |
| $` | パターンマッチでマッチした文字列の前の部分 |
| $' | パターンマッチでマッチした文字列の後の部分 |
| $+ | 最後のパターンマッチの最後にキャプチャされた文字列 |
| $^N | パターンマッチにおける最後に使われたグループ |
| @+ | 最後に成功したマッチングの最後へのオフセット |
| %+ | 最後に成功したマッチングで名前付きキャプチャの値 |
| @- | 最後マッチした先頭のオフセット |
| %- | 最後に成功したマッチングで名前付きキャプチャの値、値のリストが可能 |
| $^R | 正規表現アサートの結果 |
| ${^RE_DEBUG_FLAGS} | 正規表現デバッグフラグ |
| $ARGV | <>からの読み込んでいるときのファイル名 |
| @ARGV | コマンドライン引数 |
| ARGV | <ARGV>で@ARGVの中のファイル名に対するファイルハンドル |
| ARGVOUT | -iを使ったときの現在開いているファイルハンドル |
| $, | printのための出力フィールドの区切り文字 |
| $. | ファイルハンドルの現在の行番号 |
| $/ | 入力レコードセパレーター |
| $\ | 出力レコードセパレーター |
| $| | バッファリングしないようにする |
| ${^LAST_FH} | 最後に読み込んだファイルハンドルへのリファレンス |
| $^A | フォーマットに関する特殊変数 |
| $^L | フォーマットに関する特殊変数 |
| $% | フォーマットに関する特殊変数 |
| $- | フォーマットに関する特殊変数 |
| $: | フォーマットに関する特殊変数 |
| $= | フォーマットに関する特殊変数 |
| $^ | フォーマットに関する特殊変数 |
| $~ | フォーマットに関する特殊変数 |
| ${^CHILD_ERROR_NATIVE} | システムコールにおけるネイティブなステータス |
| $^E | 現在のOSのエラー情報 |
| $^S | 現在のインタープリタの状態 |
| $^W | 警告 |
| $! | システムコールのエラー |
| %! | システムコールのエラーナンバーと内容 |
| $? | 子プロセスのエラー |
| $@ | evalで例外をキャッチした場合に、その内容が保存される |
| $^C | コンパイルスイッチ |
| $^D | デバッグフラグ |
| ${^ENCODING} | Perlのソースコードの文字コード |
| ${^GLOBAL_PHASE} | Perlインタープリタの現在のフェーズ |
| $^H | コンパイル時ヒント |
| %^H | $^Hと同じスコープを持つ |
| ${^OPEN} | PerlIOのための内部変数 |
| $^P | デバッグのための内部変数 |
| ${^TAINT} | テイントモードかどうか |
| ${^UNICODE} | ユニコード設定 |
| ${^UTF8CACHE} | 内部UTF-8のオフセットキャッシュコードの状態 |
| ${^UTF8LOCALE} | UTF-8ロケールが検出されたかどうか |
特殊変数は、ソースコードの可読性を著しく下げるので、本当に必要になるまでは、使わないことをお勧めします。


