Seguimiento de invocaciones de métodos en el cierre de Groovy

Estoy escribiendo un pequeño DSL para la evaluación reactiva, necesito ayuda con la metaprogramación en Groovy.

Ejemplo de código DSL:

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

La función 'var' crea nuevos Signal ejemplo.

La signal función necesita una lista de Signal instancias dentro del cierre (referencias a a y b por ejemplo).

Implementación de trabajo:

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)
}

¿Hay alguna forma de esperar a que pase? it variable, por lo que la muestra se ve como

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

EDIT: Talón Signal implementación para la prueba:

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
    }
}

Caso de prueba para 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)

preguntado el 22 de mayo de 12 a las 12:05

lo que es var(1) y var(2) ¿haciendo? -

@tim_yates crea nuevos Signal instancia -

1 Respuestas

La pregunta es: "¿Hay alguna forma de evitar pasar la variable it?" Dado que a y b son variables locales y las variables locales no participan en el MOP, debería ser imposible hacerlo utilizando la metaprogramación en tiempo de ejecución.

Usar una transformación es posible, pero no sé si quieres ir tan lejos aquí

contestado el 23 de mayo de 12 a las 11:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.