Perl eval 組み込み関数は非常に強力です。この記事では、eval で正規表現を使用する方法、eval を使用してエラーをトラップする方法、eval を使用して動的コードを作成する方法、eval を使用してファイル/サブルーチンからコードを挿入する方法などを確認します。
perl eval の一般的な形式 引数として式またはコードのブロックが必要です。
1.さまざまな Perl Eval ステートメントの違い
次の perl コード スニペットを考えてみましょう:
$expr =‘$a + $b’;
eval $expr; # 1
eval “$expr”; # 2
eval ‘$expr’; # 3
eval { $expr }; #4
ケース #1 と #2 は同一であり、perl はそれらを有効な実行可能ステートメントとして識別し、式を評価します。したがって、結果は「30」になります。
ケース #3 では、式を展開できません。したがって、結果として実際の式 ($a + $b) が得られます。これは誰もが一般的に使用するものではありません.
ケース #4 はケース #3 と同じですが、コンパイル時にブロック内のステートメントの構文エラーが検証されます。
2. Eval による正規表現の処理
eval を使用すると、複数の正規表現の行と一致させる必要がある場合に、コードの行数を大幅に減らすことができます。
正規表現のリストはコンテナー (ハッシュ/配列) に入れることができ、ループ内で正規表現を 1 つずつ取得して、以下に示すように入力行と一致させることができます。
$line = <>;
%hash = (
number => qr/^[0-9]+$/,
alphabets => qr/^[a-zA-Z]+$/
);
while( my ($key,$value) = each(%hash) ) {
if(eval "$line =~ /$value/") {
print "$key\n";
}
}
3. Perl Eval エラー処理 – エラーのトラップ
Eval は、エラーをトラップするために使用されます。サブルーチンの実行中に、エラーやダイ関数の外部呼び出しにより、プログラムが停止する可能性があります。この間、perl コードのブロックが eval 内で実行される場合、プログラムはダイまたはエラーの後でも実行を継続し、エラーまたはダイイング ワードもキャプチャします。
ゼロ除算エラー:
eval { $average = $total / $count };
print “Error captured : $@\n”;
上記では、$count には値 0 が含まれています。eval ブロックなしでコードを実行すると、プログラムは終了します。
ラン・アフター・ダイ
sub func
{
die “dieing in subroutine func\n”;
}
eval { func(); };
print “Error captured : $@\n”;
Perl eval は次のエラーをキャッチできません:
- キャッチされていない信号
- メモリ不足
- 構文エラー
4. Eval を使用した動的 Perl コード
Eval は、実行時に文字列からコードをコンパイルして実行できます。したがって、eval を使用して動的 perl プログラムを作成できます。
print “Enter number 1 : ”; $data1 = ; print “Enter number 2 : ”; $data2 = ; print “Enter operator : ”; $operator = ; $str = “$data1 $operator $data2”; $result = eval “$data1 $operator $data2”;
eval では、任意の数のステートメントを実行できます。 eval の結果は、最後に評価された式です。
文字列から信頼できないデータを実行する可能性があるため、文字列で eval を使用する場合は注意が必要です。割り当て操作を文字列自体で行う必要がある場合は、左辺値の取り扱いに注意する必要があります。
$str = “\$result = $data1 $operator $data2”;
eval { $str };
5.実行時にファイルまたはサブルーチンから Perl スクリプトを挿入する
perl では、実行時にモジュールを動的にロードできます。モジュールを動的にロードするには、(「use」ではなく「require」を使用する必要があります。
入力ファイルが圧縮されている場合にモジュールをロードするサンプルコード
$filetype = `file $InputFile`;
if($filetype =~ /gzip compressed/) {
print "compressed input file...\n";
eval { require PerlIO::gzip; };
}
プログラムで使用される共通のサブルーチンは、以下に示すように、eval によって perl プログラムにロードできるファイルに分割できます。
File : common_routines.pl
sub open_file
{
....
}
sub read_file
{
....
}
sub write_file
{
....
}
sub close_file
{
....
}
In the perl script,
sub load_file_subroutines
{
open CODE, 'common_routines.pl';
undef $\;
my $code = <code>;
close CODE;
eval $code;
die $@ if $@;
}</code>
6.入力タイムアウトでの Perl 評価
アラーム標準ライブラリ関数は、一定時間後に SIGALRM シグナルを生成するために使用されます。これは主に、ユーザー入力のブロッキング待機を回避するのに役立ちます。以下の例に示すように、これを eval で使用して、指定された時間内にユーザー入力を取得できます。
$SIG{ALRM} = \&input_timed_out;
eval {
alarm (10);
$buf = <>;
alarm(0); # Cancel the pending alarm if user responds.
};
if ($@ =~ /NO USER INPUT IN TIME/) {
print "Timed out.\n";
}
sub input_timed_out {
die "NO USER INPUT IN TIME";
}