1

私はリアクティブ評価用の小さなDSLを書いていますが、Groovyでのメタプログラミングの助けが必要です。

サンプルDSLコード:

Signal<Integer> a = var(1)
Signal<Integer> b = var(2)
Signal<Integer> c = signal { a(it) + b(it) }

'var'関数は新しいSignalインスタンスを作成します。

このsignal関数にはSignal、クロージャー内のインスタンスのリストが必要です(例への参照ab例)。

実用的な実装:

interface Signal<T> {
    T now()
}

Signal.metaClass.call = { dependencies ->
    dependencies?.add(delegate)
    delegate.now()
}

def signal = { Closure<?> body ->
    def dependencies = new HashSet<>()
    body.call(dependencies)
    createSignal(dependencies, body)
}

変数の受け渡しを回避する方法はありますか?itサンプルは次のようになります

Signal<Integer> a = var(1)
Signal<Integer> b = var(2)
Signal<Integer> c = signal { a() + b() }

編集:テスト用の スタブSignal実装:

class SignalStub<T> implements Signal<T> {
    T value
    Collection<Signal<?>> dependencies

    static def var(value) { new SignalStub<>(value: value, dependencies: [])}
    static def createSignal(deps, body) { new SignalStub<Object>(value: body.call(), dependencies: deps) }

    @Override
    T now() {
        return value
    }
}

DSLのテストケース:

def a = var(1)
def b = var(2)

def c = signal { a() + b() }

assert c.now() == 3
assert c.dependencies.contains(a)
assert c.dependencies.contains(b)
4

1 に答える 1

1

問題は、「it 変数を渡さないようにする方法はありますか?」ということです。a と b はローカル変数であり、ローカル変数は MOP に参加していないため、ランタイム メタ プログラミングを使用して行うことは不可能なはずです。

変換を使用することは可能ですが、ここまで行きたいかどうかはわかりません

于 2012-05-23T10:05:53.430 に答える