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"; }