- eval EXPR
- eval BLOCK
- eval
-
eval
in all its forms is used to execute a little Perl program, trapping any errors encountered so they don't crash the calling program.どの型式の
eval
も、小さな Perl のプログラムであるかのように実行され、 遭遇した全てのエラーをトラップするので、呼び出したプログラムが クラッシュすることはありません。Plain
eval
with no argument is justeval EXPR
, where the expression is understood to be contained in$_
. Thus there are only two realeval
forms; the one with an EXPR is often called "string eval". In a string eval, the value of the expression (which is itself determined within scalar context) is first parsed, and if there were no errors, executed as a block within the lexical context of the current Perl program. This form is typically used to delay parsing and subsequent execution of the text of EXPR until run time. Note that the value is parsed every time theeval
executes.引数なしの
eval
は単にeval EXPR
で、式は$_
に 含まれているものとして考えられます。 従って実際には二つだけのeval
形式があります: EXPR のものはしばしば「文字列 eval」(string eval) と呼ばれます。 「文字列 eval」では、 式の値(それ自身スカラコンテキストの中で決定されます)はまずパースされ、 エラーがなければ Perl プログラムのレキシカルコンテキストの中のブロックとして 実行されます。 この形は主に EXPR のテキストのパースと実行を実行時にまで 遅延させるのに用います。 返される値はeval
が実行されるごとにパースされることに注意してください。The other form is called "block eval". It is less general than string eval, but the code within the BLOCK is parsed only once (at the same time the code surrounding the
eval
itself was parsed) and executed within the context of the current Perl program. This form is typically used to trap exceptions more efficiently than the first, while also providing the benefit of checking the code within BLOCK at compile time. BLOCK is parsed and compiled just once. Since errors are trapped, it often is used to check if a given feature is available.もう一つの型式は「ブロック eval」と呼ばれます。 これは文字列 eval ほど一般的ではありませんが、 BLOCK 内部のコードは一度だけパースされ (コードを 囲む
eval
自身がパースされるのと同じ時点です) 現在の Perl プログラムのコンテキストで実行されます。 この形式は典型的には第一の形式より効率的に例外をトラップします; また BLOCK 内部のコードはコンパイル時にチェックされるという利点を提供します。 BLOCK は一度だけパース及びコンパイルされます。 エラーはトラップされてるので、しばしば与えられた機能が利用可能かを チェックするために使われます。In both forms, the value returned is the value of the last expression evaluated inside the mini-program; a return statement may also be used, just as with subroutines. The expression providing the return value is evaluated in void, scalar, or list context, depending on the context of the
eval
itself. See wantarray for more on how the evaluation context can be determined.どちらの形式でも、返される値はミニプログラムの内部で最後に評価された 表現の値です; サブルーチンと同様、return 文も使えます。 返り値として提供される表現は、
eval
自身のコンテキストに 依存して無効・スカラ・リストのいずれかのコンテキストで評価されます。 評価コンテキストの決定方法についての詳細は wantarray を 参照してください。If there is a syntax error or runtime error, or a die statement is executed,
eval
returns undef in scalar context, or an empty list in list context, and$@
is set to the error message. (Prior to 5.16, a bug caused undef to be returned in list context for syntax errors, but not for runtime errors.) If there was no error,$@
is set to the empty string. A control flow operator like last or goto can bypass the setting of$@
. Beware that usingeval
neither silences Perl from printing warnings to STDERR, nor does it stuff the text of warning messages into$@
. To do either of those, you have to use the$SIG{__WARN__}
facility, or turn off warnings inside the BLOCK or EXPR usingno warnings 'all'
. See warn, perlvar, and warnings.構文エラーや実行エラーが発生するか、die 文が実行されると、
eval
はスカラコンテキストでは undef が、 リストコンテキストでは空リストが設定され、$@
にエラーメッセージが設定されます。 (5.16 以前では、バグによって、リストコンテキストで構文エラーの時には undef を返していましたが、実行エラーの時には 返していませんでした。) エラーがなければ、$@
は空文字列に設定されます。 last や goto のようなフロー制御演算子は$@
の設定を回避できます。eval
を、STDERR に警告メッセージを表示させない目的や、 警告メッセージを$@
に格納する目的では使わないでください。 そのような用途では、$SIG{__WARN__}
機能を使うか、no warnings 'all'
を使って BLOCK か EXPR の内部での警告を オフにする必要があります。 warn, perlvar, warnings を参照してください。Note that, because
eval
traps otherwise-fatal errors, it is useful for determining whether a particular feature (such as socket or symlink) is implemented. It is also Perl's exception-trapping mechanism, where the die operator is used to raise exceptions.eval
は、致命的エラーとなるようなものを トラップすることができるので、 (socket や symlink といった) 特定の機能が 実装されているかを、 調べるために使うことができることに注意してください。 die 演算子が例外を発生させるものとすれば、これはまた、 Perl の例外捕捉機能と捉えることもできます。Before Perl 5.14, the assignment to
$@
occurred before restoration of localized variables, which means that for your code to run on older versions, a temporary is required if you want to mask some, but not all errors:Perl 5.14 より前では、
$@
への代入はローカル化された変数の 復帰の前に起きるので、古いバージョンで実行される場合は、全てではなく一部だけの エラーをマスクしたい場合には一時変数が必要です:# alter $@ on nefarious repugnancy only { my $e; { local $@; # protect existing $@ eval { test_repugnancy() }; # $@ =~ /nefarious/ and die $@; # Perl 5.14 and higher only $@ =~ /nefarious/ and $e = $@; } die $e if defined $e }
There are some different considerations for each form:
それぞれの型式について、異なった考慮事項があります:
- String eval
-
(文字列 eval)
Since the return value of EXPR is executed as a block within the lexical context of the current Perl program, any outer lexical variables are visible to it, and any package variable settings or subroutine and format definitions remain afterwards.
EXPR の返り値は現在の Perl プログラムのレキシカルコンテキストの中で 実行されるので、外側のレキシカルスコープはそこから見え、 パッケージ変数設定やサブルーチンとフォーマット設定は後に残ります。
Note that when
BEGIN {}
blocks are embedded inside of an eval block the contents of the block will be executed immediately and before the rest of the eval code is executed. You can disable this entirely byeval ブロック内に
BEGIN {}
ブロックが組み込まれている場合、 ブロックの内容は直ちに、eval コードの残りの部分が実行される前に 実行されます。 これは次のようにして完全に向こうにすることができ:local ${^MAX_NESTED_EVAL_BEGIN_BLOCKS} = 0; eval $string;
which will cause any embedded
BEGIN
blocks in$string
to throw an exception.これは
$string
の中の組み込みのBEGIN
ブロックで例外を引き起こします。- Under the
"unicode_eval"
feature -
If this feature is enabled (which is the default under a
use 5.16
or higher declaration), Perl assumes that EXPR is a character string. Anyuse utf8
orno utf8
declarations within the string thus have no effect. Source filters are forbidden as well. (unicode_strings
, however, can appear within the string.)この機能が有効の場合(これは
use 5.16
またはそれ以上が 宣言されている場合はデフォルトです)、 Perl は EXPR が文字の文字列であると仮定します。 従って文字列中のuse utf8
やno utf8
宣言は無効です。 ソースフィルタも禁止されます。 (しかし、unicode_strings
は文字列の中に現れます。)See also the evalbytes operator, which works properly with source filters.
ソースフィルタが適切に動作する evalbytes 演算子も参照してください。
- Outside the
"unicode_eval"
feature -
In this case, the behavior is problematic and is not so easily described. Here are two bugs that cannot easily be fixed without breaking existing programs:
この場合、振る舞いには問題があり、それほど簡単には説明できません。 既存のプログラムを壊さずに簡単に修正することが出来ない二つのバグがあります:
-
Perl's internal storage of EXPR affects the behavior of the executed code. For example:
Perl's internal storage of EXPR の Perl の内部ストーレージは実行されるコードの振る舞いに影響を与えます。 例えば:
my $v = eval "use utf8; '$expr'";
If $expr is
"\xc4\x80"
(U+0100 in UTF-8), then the value stored in$v
will depend on whether Perl stores $expr "upgraded" (cf. utf8) or not:$expr が
"\xc4\x80"
(U+0100 in UTF-8) の場合、$v
に保管される値は、 Perl が $expr を「昇格」(utf8 参照)して保管するかどうかによります:If upgraded,
$v
will be"\xc4\x80"
(i.e., theuse utf8
has no effect.)(昇格されると、
$v
will be"\xc4\x80"
になります (つまり、use utf8
は無効です。))If non-upgraded,
$v
will be"\x{100}"
.(昇格されないと、
$v
は"\x{100}"
です。)
This is undesirable since being upgraded or not should not affect a string's behavior.
昇格するかどうかは文字列の振る舞いに影響を与えるべきではないので、 これは望ましくないです。
-
Source filters activated within
eval
leak out into whichever file scope is currently being compiled. To give an example with the CPAN module Semi::Semicolons:eval
の中で有効にされたソースフィルタは、現在どちらのファイルスコープで コンパイルされているかをリークさせます。 CPAN モジュール Semi::Semicolons を使った例は:BEGIN { eval "use Semi::Semicolons; # not filtered" } # filtered here!
evalbytes fixes that to work the way one would expect:
evalbytes は、人が想定するだろう手法で動作するように これを修正します:
use feature "evalbytes"; BEGIN { evalbytes "use Semi::Semicolons; # filtered" } # not filtered
-
Problems can arise if the string expands a scalar containing a floating point number. That scalar can expand to letters, such as
"NaN"
or"Infinity"
; or, within the scope of ause locale
, the decimal point character may be something other than a dot (such as a comma). None of these are likely to parse as you are likely expecting.文字列をが小数点を含むスカラを展開するときに問題が起こることがあります。 そのようなスカラは
"NaN"
や"Infinity"
のような文字に 展開されることがあります; または、use locale
のスコープの中では、 小数点文字は (カンマのような) ドット以外の文字かもしれません。 これらはどれもあなたがおそらく予測しているようにはパースされません。You should be especially careful to remember what's being looked at when:
以下のような場合に、何が調べられるかに特に注意しておくことが必要です:
eval $x; # CASE 1 eval "$x"; # CASE 2 eval '$x'; # CASE 3 eval { $x }; # CASE 4 eval "\$$x++"; # CASE 5 $$x++; # CASE 6
Cases 1 and 2 above behave identically: they run the code contained in the variable $x. (Although case 2 has misleading double quotes making the reader wonder what else might be happening (nothing is).) Cases 3 and 4 likewise behave in the same way: they run the code
'$x'
, which does nothing but return the value of $x. (Case 4 is preferred for purely visual reasons, but it also has the advantage of compiling at compile-time instead of at run-time.) Case 5 is a place where normally you would like to use double quotes, except that in this particular situation, you can just use symbolic references instead, as in case 6.上記の CASE 1 と CASE 2 の動作は同一で、変数 $x 内の コードを実行します。 (ただし、CASE 2 では、必要のないダブルクォートによって、 読む人が何が起こるか混乱することでしょう (何も起こりませんが)。) 同様に CASE 3 と CASE 4 の動作も等しく、$x の値を返す以外に 何もしない
$x
というコードを実行します。 (純粋に見た目の問題で、CASE 4 が好まれますが、 実行時でなくコンパイル時にコンパイルされるという利点もあります)。 CASE 5 の場合は、通常ダブルクォートを使用 します; この状況を除けば、CASE 6 のように、単に シンボリックリファレンスを使えば良いでしょう。An
eval ''
executed within a subroutine defined in theDB
package doesn't see the usual surrounding lexical scope, but rather the scope of the first non-DB piece of code that called it. You don't normally need to worry about this unless you are writing a Perl debugger.DB
パッケージで定義されたサブルーチン内でeval ''
を実行すると、通常の レキシカルスコープではなく、これを呼び出した最初の非 DB コード片の スコープになります。 Perl デバッガを書いているのでない限り、普通はこれについて心配する必要は ありません。The final semicolon, if any, may be omitted from the value of EXPR.
最後のセミコロンは、もしあれば、EXPR の値から省くことができます。
- Under the
- Block eval
-
If the code to be executed doesn't vary, you may use the eval-BLOCK form to trap run-time errors without incurring the penalty of recompiling each time. The error, if any, is still returned in
$@
. Examples:実行するコードが変わらないのであれば、毎回多量の再コンパイルすることなしに、 実行時エラーのトラップを行なうために、 eval-BLOCK 形式を使うことができます。 エラーがあれば、やはり
$@
に返されます。 例:# make divide-by-zero nonfatal eval { $answer = $x / $y; }; warn $@ if $@; # same thing, but less efficient eval '$answer = $x / $y'; warn $@ if $@; # a compile-time error eval { $answer = }; # WRONG # a run-time error eval '$answer ='; # sets $@
If you want to trap errors when loading an XS module, some problems with the binary interface (such as Perl version skew) may be fatal even with
eval
unless$ENV{PERL_DL_NONLAZY}
is set. See perlrun.XS モジュールのロード中のエラーをトラップしたいなら、 (Perl バージョンの違いのような) バイナリインターフェースに関する問題に ついては
$ENV{PERL_DL_NONLAZY}
がセットされていないeval
でも致命的エラーになるかもしれません。 perlrun を参照してください。Using the
eval {}
form as an exception trap in libraries does have some issues. Due to the current arguably broken state of__DIE__
hooks, you may wish not to trigger any__DIE__
hooks that user code may have installed. You can use thelocal $SIG{__DIE__}
construct for this purpose, as this example shows:eval{}
形式をライブラリの例外を捕捉するために使うときには 問題があります。 現在の__DIE__
フックの状態はほぼ確実に壊れているという理由で、 ユーザーのコードが設定した__DIE__
フックを実行したくないかもしれません。 この目的には以下の例のように、local $SIG{__DIE__}
構造が使えます。# a private exception trap for divide-by-zero eval { local $SIG{'__DIE__'}; $answer = $x / $y; }; warn $@ if $@;
This is especially significant, given that
__DIE__
hooks can call die again, which has the effect of changing their error messages:これは特に顕著です; 与えられた
__DIE__
フックは die を もう一度呼び出すことができ、これによってエラーメッセージを変える 効果があります:# __DIE__ hooks may modify error messages { local $SIG{'__DIE__'} = sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x }; eval { die "foo lives here" }; print $@ if $@; # prints "bar lives here" }
Because this promotes action at a distance, this counterintuitive behavior may be fixed in a future release.
これは距離の離れた行動であるため、この直感的でない振る舞いは 将来のリリースでは修正されるかもしれません。
eval BLOCK
does not count as a loop, so the loop control statements next, last, or redo cannot be used to leave or restart the block.eval BLOCK
はループとして 扱われません; 従って、next, last, redo といったループ制御文で ブロックから離れたり再実行したりはできません。The final semicolon, if any, may be omitted from within the BLOCK.
最後のセミコロンは、もしあれば、BLOCK の中から削除されます。