2011-12-13 3 views
2

groovyでフローを表現するためのDSLを書いています。私は、フローの特定のポイントで保存され、評価される関数を書く能力をユーザに提供したいと考えています。ような何か:今groovyスクリプトが埋め込まれたGroovy DSL

states { 
    "checkedState" { 
     onEnter {state-> 
      //do some groovy things with state object 
     } 
    } 
} 

は、私は引用符で囲む閉鎖をして、それを格納することができ、かなり確信しています。しかし、これらのDSLを編集するときには、可能な限りシンタックスハイライトとコンテンツアシストを維持したいと考えています。私は、別のコンテキストでクロージャーを実行するときにもはや有効ではない周囲のフロー定義からクロージャーCOULD参照アーティファクトが発生することを認識しており、これで問題はありません。実際には、非クロージャー関数定義にクロージャー構文を使用したいと思います。

tl; dr; DSLをデータベースに保存して後でスクリプトホストで実行できるように、クロージャのコードを取得する必要があります。

答えて

2

この情報はコンパイル時に破棄されるため、クロージャのソースコードを取得する方法はないと思います。おそらく、実行時にクロージャの構文ツリーを利用できるようにするAST transformationを書くことができます。

データベースにクロージャを格納することが気になる人で、後でソースコードにアクセスする必要がない場合は、シリアライズしてシリアル化されたフォームを保存してみてください。

ClosureSerializableを実装し、そのownerthisObjectdelegate属性をゼロにした後、私はそれをシリアル化することができましたが、私は、逆シリアル化にClassNotFoundExceptionを取得しています。いくつか検索した後

def myClosure = {a, b -> a + b} 

Closure.metaClass.setAttribute(myClosure, "owner", null) 
Closure.metaClass.setAttribute(myClosure, "thisObject", null) 
myClosure.delegate = null 

def byteOS = new ByteArrayOutputStream() 
new ObjectOutputStream(byteOS).writeObject(myClosure) 
def serializedClosure = byteOS.toByteArray() 

def input = new ObjectInputStream(new ByteArrayInputStream(serializedClosure)) 
def deserializedClosure = input.readObject() // throws CNFE 

、私はおそらく、リモートマシン上で、クロージャをシリアライズし、後でそれを実行可能にするために特別に作成ライブラリ、Groovy Remote Controlを発見しました。試してみてください。おそらくそれはあなたが必要とするものです。

+0

偉大な回答ありがとう!あらかじめ構築されたASTレンダリングライブラリの不足でこの答えが勝つでしょうが、私は他の人が答えるのにもう少し時間を与えます。 –

関連する問題