【发布时间】:2012-05-22 11:47:50
【问题描述】:
我正在编写一个用于响应式评估的小型 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 实例列表(在示例中引用a 和b)。
工作实施:
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)
【问题讨论】:
-
var(1)和var(2)在做什么? -
@tim_yates 它创建新的
Signal实例
标签: groovy dsl reactive-programming