PerlならサンプルコードPerl入門

2016-11-02

特殊変数の一覧

  1. Perl
  2. 特殊変数

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
CentOSLinux

その他の特殊変数

$$ - プロセス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, $bsort関数で使う変数
%ENV環境変数
$^Fファイル記述子の最大値
@F自動スプリットモードが有効の場合、それぞれの行のフィールドを含む
@INCライブラリの読み込みパスのリスト
%INCインクルードされたファイルの名前の一覧
$^I置き換え変数の拡張子
$^Mメモリが足りなくなった場合にトラップするか
$^Oオペレーティングシステムの名前
%SIGシグナルハンドラ
$^Tプログラムを開始した時刻
$^VPerlのバージョン情報
$^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ロケールが検出されたかどうか

特殊変数は、ソースコードの可読性を著しく下げるので、本当に必要になるまでは、使わないことをお勧めします。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証