Groovy闭包中的跟踪方法调用

时间:2012-05-22 11:47:50

标签: groovy dsl reactive-programming

我正在编写一个用于反应评估的小型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() }

修改 Stub 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)

1 个答案:

答案 0 :(得分:1)

问题是:“有没有办法避免传递it变量?” 由于a和b是局部变量而局部变量没有参与MOP,因此不可能使用运行时元编程。

使用转换是可能的,但我不知道你是否想在这里走得那么远