eval - 例外のキャッチ、文字列の動的実行
eval関数を使用すると、ブロック構文の場合は、例外をキャッチすることができます。文字列構文の場合は、文字列を動的に実行することができます。
# evalブロック - 例外のキャッチ eval { ... }; # eval文字列 - 文字列を動的に実行 eval $string;
ブロックの構文と、文字列の構文は、機能がまったく異なるので注意してください。それぞれの構文について詳しく解説します。
例外のキャッチ - evalブロック
evalブロックと呼ばれている方は、Perlにおける例外のキャッチの構文です。
# evalブロック - 例外のキャッチ eval { ... };
これは、Javaなどにおける例外処理のcatch構文と同じ役割を果たします。evalブロックの中で、例外が発生した場合に、例外をキャッチし、プログラムが終了するのを防ぐことができます。
例外の内容は特殊変数「$@」に代入されているので、これをチェックしましょう。$@は、他の処理によって上書きされる可能性があるので、変数に保存しておくことがお勧めです。
if (my $error = $@) { print "$error\n"; }
Perlの例外処理についての詳しい解説は以下の記事をご覧ください。
文字列の動的実行 - eval文字列
eval文字列と呼ばれる方は、文字列を動的に実行する構文です。evalに文字列を渡すとその文字列をPerlの実行文として実行します。実行時に発生したエラーは$@に格納されます。
# eval文字列 - 文字列を動的に実行 eval $string;
ひとつの例としてサブルーチンを実行時に定義することができます。以下の例はfooという5を返すサブルーチンをeval文字列と型グロブを実行時に定義しています。「no string 'refs'」でシンボリックリファレンスを一時的に許可しています。
{ no strict 'refs'; *{"foo"} = eval "sub { return 5 }"; }
これはCPANモジュールで、アクセッサを作成するモジュールなどで、利用されています。
eval文字列の危険性
でも、普通のプログラミングでは、eval文字列を使わないことを推奨します。
evalは渡された文字列をそのまま実行してしまうのでセキュリティという観点で望ましくないです。業務でアプリケーションを作成する場合であれば、eval文字列は使う場面はまずありません。
CPANモジュール作成者が目標なら、eval文字列は、ぜひ知っておいてほしい知識です。