1. ホーム
  2. スクリプト・コラム
  3. パール

Perlのeval関数の使用例

2022-01-28 12:11:39

Perlはリアルタイムにコードを生成して実行するスクリプト言語です。この機能により、コードのコンパイルが実行時に延期されるため、quot;ダイナミックコード"と呼ばれています。また、PerlはJavaやC++のような例外処理機構を備えています。今回は、Perlの動的コードと例外処理機構を実装している関数、evalについて説明します。もし間違いがあれば、遠慮なく議論・批判してください。

eval関数は、Perlのコードの一部を引数とするPerlの仮想マシンと考えることができます。eval 関数の使い方は 'perldoc -f eval' で知ることができます。

コピーコード コードは以下の通りです。

eval EXPR

EXPRは、例えば、以下のような表現です。

コピーコード コードは以下の通りです。

eval "print $a" ;
eval 'print $a' . ', $b' ;
eval 1 + 3 ;
eval 'print ' . '$a + $b, "\n"' ;
eval $command;#$command = 'print "hello Perl"'
eval $ARGV[0];

実行されると、Perl インタープリタはまず式の値を解析し、その式の値を Perl ステートメントとして現在の実行コンテキストに挿入します。つまり、新しく生成された文は eval 文自身と同じコンテキスト環境を持つことになります。このようにして、eval 文が実行されるたびに、式が解析されます。そのため,ループの中で eval EXPR が実行されると,式は何度も解析されることになります.このように eval を使うことで,Perl スクリプトはリアルタイムにコードを生成し,実行することができますので,動的コード (dynamic code) を実現することができます.

コピーコード コードは以下の通りです。

eval BLOCK

BLOCKは、次のようなコードのブロックです。

コピーコード コードは以下の通りです。

eval {print $a};
eval {$a = 1, $b = 2, $c = $a + $b};

最初のアプローチとは異なり、BLOCK は一度だけパースされ、その後、現在の eval 関数の実行コンテキストにその全体が挿入されます。パースによるパフォーマンス上の利点と、コンパイル時にコードの構文をチェックできることから、このアプローチは、前者のアプローチも可能ですが、Perlとしてコードの一部に例外捕捉機構を提供するためによく使用されます。

eval 引数プログラムは、ヘルプ名で "ミニプログラム" と呼ばれています。いずれの場合も、eval 関数の戻り値はミニプログラムの最後の文の値であり、戻り値文に遭遇した場合はサブルーチンと同じになります。

Script1:

コピーコード コードは以下の通りです。

#! /usr/bin/perl -w
push ( @program,'$i = 1;');
push ( @program,'$i = 3; $j = 2; $k = $i + $j');
push ( @program, '$i = 3; return 24; $k = $i + $j');
foreach $exp (@program)
{
    $rtn =eval($exp);
    print $rtn,"\n";
}

出力します。

コピーコード コードは以下の通りです。

1
5
24

アプレットがシンタックスエラー、ランタイムエラー、または die ステートメントを起こした場合、eval は undef を返します。エラーコードは$@に格納されます。

Script2:

コピーコード コードは以下の通りです。

#! /usr/bin/perl -w
push ( @program, '$i = 3; die "error message"; $k = $i + $j');
foreach $exp (@program)
{
    $rtn =eval($exp);
    if ( ! defined ( $rtn))
    {
       print "Exception: " , $@,"\n";
    }
    else
    {
       print $rtn,"\n";
    }
} ;

出力します。

コピーコード コードは以下の通りです。

Exception: error message at (eval 1) line 1.

Script3です。

コピーコード コードは以下の通りです。

#! /usr/bin/perl -w
# a run-time error
eval '$answer =' ; # sets $@
warn $@ if$@;

出力します。
コピーコード コードは以下の通りです。

syntax error at (eval 1) line 2, at EOF