7

古いソースコードを掘り下げていると、次のことがわかりました。

my $module = $some{module};
eval "require $module";
die "Bad module\n$@" if $@;

私はコードが何をするかを理解していますが、モジュールを「要求」しようとし、失敗すると終了します - perlcritic はそれについて不平を言います

331 行 13 列目の「eval」の表現形式。PBP の 161 ページを参照してください。(重大度: 5)

残念ながら、私は PBP の本を持っていないので、上記の正しい方法は何だろう...

また、同じソースで次のことが見つかりました。

sub test_repo_file {
    my($self, $repo, $test) = @_;
    my $abspath = repo_abs_path($repo);
    return "eval -$test $abspath";
}

ここでは、何が「eval」を解決するのか理解できず、perlcritic は「string eval」について再び不平を言います...

「string eval」に関する基本的なポイントと、上記を正しく記述する方法を誰かが説明してもらえますか?

4

2 に答える 2

8

実行perlcritic --verbose '%d\n'すると、説明も表示されます。

`eval' の文字列形式は実行されるたびに再コンパイルされますが、ブロック形式は一度だけコンパイルされます。また、文字列形式はコンパイル時の警告を出しません。

   eval "print $foo";        # not ok
   eval {print $foo};        # ok

最初のケースに適用されます。

2 番目のケースでは、メッセージは生成されません。むしろそうじゃないですか

return eval "-$test $abspath"

ここではブロック評価を使用できません。$test に必要なものが実際に含まれていることを確認する必要があります

$test =~ /^[a-z]$/i

$abspath の評価を回避します。

eval "-$test \$abspath"

それでよろしければ、追加できます

## no critic

行の終わりまで。

于 2015-04-15T22:29:04.120 に答える
5

を使用する必要があるユーザーはほとんどいないはずeval EXPRです。ほとんどの場合、テンプレート システムとして使用すべきではない場合 (例: s/.../eval($repl)/e)、または使用すべきときに例外をキャッチするためにeval BLOCK使用されます。

使用する理由がある場合は、生成されたコードまたはユーザーが送信したコードを実行するためです。コードの生成はトリッキーでエラーが発生しやすく、エラーはセキュリティに影響します。ユーザーが送信したコードを実行することは、セキュリティ上の大きな懸念事項です。そのため、 の使用はすべてeval EXPR慎重に検討する必要があります。

perlcritic事実上すべての使用が重大なセキュリティへの影響を伴うエラーであることを考えると、その使用にフラグを立てることは非常に適切です。


あなたの場合、の使用eval EXPRは最適ではありません。私は使うだろう

my $path = $module . ".pm";
$path =~ s{::}{/}g;
eval { require $path }

はい、これはポータブルです。

于 2015-04-15T22:57:58.267 に答える