1

MVEL を使用してカスタムのプリコンパイル済み関数を定義し、その関数を別のコンパイル済み式で使用することはできますか? 次のことを試してみると:

MVEL.compileExpression("function hello() { System.out.println(\"Hello!\"); hello(); return x * y;");

Exception in thread "main" [Error: duplicate function: hello]2回目に実行しようとすると取得します。

式自体ではなく、何らかのコンテキストで関数を宣言する必要があるようです。しばらく ParsedContext で遊んでいましたが、常にException in thread "main" [Error: unable to access property (null parent): hello].

インターネットには、さまざまな MVEL 言語の使用に関するトピックをカバーするチュートリアルがたくさんありますが、そのような埋め込みトピックの文書化は非常に不十分です。私が間違っていることを教えてください。

PS Javaからいくつかの機能を実行したくありません。MVEL で動的に定義する必要があります。

4

1 に答える 1

8

これは可能ですが、いくつかの一般的なユースケースよりも少し注意が必要です。

基本的に、あなたがする必要があるのは、次のようにあなたの関数を定義するスクリプトを作成することです:

VariableResolverFactory functionFactory = new MapVariableResolverFactory();
MVEL.eval("def foo() { System.out.println("foo"); }; def bar() { System.out.println("bar") };", functionFactory);

次に、このファクトリを実行する式にバックチェーンします。

VariableResolverFactory myVarFactory = new MapVariableResolverFactory();
myVarFactory.setNextFactory(functionFactory);

Serializable s = MVEL.compileExpression("foo(); bar();");

MVEL.executeExpression(s, myVarFactory);

関数は変数テーブルに参照として記録されるため、通常の変数ファクトリバックチェーンを使用してMVELで関数を共有できます。

注:「myVarFactory」を再共有しないでください。毎回新しいものを作成したい。上記のように、「functionFactory」をリサイクルして、実行ごとのファクトリにバックチェーンするだけです。そうしないと、実行間でローカル変数の状態を共有することになります-そしてそれはスレッドセーフではありません

于 2012-09-29T00:58:39.067 に答える