2012-05-22 4 views
1

반응 평가를위한 작은 DSL을 작성 중이므로 Groovy에서 메타 프로그래밍과 관련하여 도움이 필요합니다.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 변수를 전달 awoit 수있는 방법이 있나요

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) 
+0

무엇 가고 싶은 경우 나도 몰라 변환을 사용? –

+0

@tim_yates 새로운'Signal' 인스턴스를 생성합니다 – miah

답변

1

질문 : "는 그 변수를 전달하지 않도록 할 수있는 방법이 있습니까?" a와 b는 지역 변수이고 지역 변수는 MOP에 참여하지 않으므로 런타임 메타 프로그래밍을 사용하여 수행 할 수 없어야합니다.

A는 것이 가능하지만`VAR (1)`와`VAR (2)`일을 멀리 여기