2017-03-20 1 views
2

私はperl newbです。perlユーザが提供するサブで、常に評価を行わずにテキストを返します

残念ながら、evalは私が

を期待していように動作しません。私のモック例:

my $filter = 'return false;'; 
my $filterFunc = sub{ eval{ $filter } } ; 
while (my $entry = readNextEntry()){ 
    print "Eval:".$filterFunc->($entry)."\n"; 
} 

私はこれを実行すると、私は(というよりも、すべてのパスから返されるリテラル"return false;"を取得関数が評価される)。私はいくつかのバリエーションを試しましたが、私は魔法の組み合わせを打つことはありません。セキュリティへの影響について

注:私は、ユーザーを午前として、私はコードがない、渡されたかについてのセキュリティ上の懸念を持っていない

私の目的は、パラメータが有用であるかどうかわからないので、複数のソースを引き込み、パラメータに基づいてフィルタリングすることです。テキストを渡すことができると思いました。eval匿名関数、各レコードの関数を実行します(フィルター関数)。私はユーザーであるため、渡されたコードが何をしているかについてセキュリティ上の懸念はありません。

+2

あなたのアプローチがうまくいくと思いますが、私はあなたが 'eval'についてあまり心配するべきではないと思いますが、私はまださまざまな種類のフィルタを実装する方が安全だと言うでしょう。必要に応じてそれらを引数で呼び出す。ディスパッチテーブルはここで便利です。あなた自身をユーザーとして信用しないでください。 – simbabque

+0

私はまったく別の解決策には間違いありません。私は*非常に*一般的なクエリユーティリティを実装しようとしています。その評価へのポイントは、常に真/偽を返し、決して他のことをしない関数に解決されるはずです。短期的には、明らかに私はちょうどevalの仕組みを間違って読んでいます。 –

+1

あなたは何を照会していますか?データが何らかの方法でレコードに基づいている場合は、リレーショナルデータベースにロードしてSQLを使用してください。私はそれがクエリにうまくいくと聞いています。 – simbabque

答えて

4

あなたは文字列eval、ないブロックevalを行う必要があります。

my $filterFunc = sub{ eval{ $filter } } ; 

eval BLOCKtry/catch機構のようなものです。任意のコードは評価されません。ブロック内のコードのエラーをキャッチします。あなたが望むのは、文字列evalです。ここで

my $filterFunc = sub{ eval $filter }; 

は、私はあなたがやろうとしていると思うものの実装例です:

$ perl -E 'my $filter = sub { my $f = shift; eval $ARGV[0]; }; for (1 .. 10) { say $_ if $filter->($_) }' '$f % 2' 
1 
3 
5 
7 
9 

しかし、Perlで何falseはありません。それはキーワードではありません。 がどこかにある場合を除き、use strictがあるかどうかによって構文エラーが発生することがあります。

あなたはread up on evalです。


あなたが望むすべてではなく0を使用し、偽の何かを返す$filterFuncある場合。リテラル文字列"return false;"はPerlでであることに注意してください。

+0

「return false」は、私が打つ次の問題でした –

関連する問題