2012-05-24 4 views
2

내 DSL의 규칙에 '활성'플래그를 구현하고 싶습니다.Groovy DSL : 클로저의 속성 설정

Script dslScript = new GroovyShell().parse(new File("Standard")) 

dslScript.metaClass.Shipping = { String name, Closure cl -> 
    ShippingDelegate delegate = new ShippingDelegate() 
    delegate.name = name 
    cl.delegate = delegate 
    cl.setResolveStrategy Closure.DELEGATE_FIRST 
    cl() 
} 

dslScript.run() 

ShippingDelegate은 간단하다 : 그것은 모두가 불만없이 잘 실행

class ShippingDelegate { 

    String name 

    void rules(Closure cl) { 
    ... do stuff here 
    } 
} 

다음
Shipping("Standard") { 
    active: true 
    description: "some text" 

    rules { 
     ... define rules here 
    } 
} 

나는 다음과 같은 몇 가지 튜토리얼을 실행하는 모든 것을 가지고 방법은 다음과 같습니다 여기에 내가 그것을 같이하고 싶었 방법 어떻게 '활성'또는 '설명'에 액세스 할 수 있습니까?

어쨌든이 구문은 실제로 무엇을합니까? 맵 할당과 같지만 아무 것도 없습니다. 아니면 그루비 컴파일러가 불완전한 삼항 연산자로 취급합니까?

답변

4

디자인을 단순화 할 수 있도록 DSL에 약간의 변경을 제안 할 수 있습니까?

편집 된 경우, 둘 이상의 배송 인스턴스가있는 경우 예가 명확하지 않습니다.

shipping("Standard") { 
    active= true 
    description= "some text" 

    rules { 
     ... define rules here 
    } 
} 
shipping("International") { 
    active= true 
    description= "some text" 

    rules { 
     ... define rules here 
    } 
} 

즉 : 내 두 번째 시도에서, 나는 대답은 DSL이 변경되어야합니다

class ShippingRules { 
    boolean active 
    String description 
    String name 


    ShippingRules(String name) { 
     this.name=name 
    } 

    def rules(Closure c) { 
     c.delegate=this 
     c() 
    } 
} 



abstract class ShippingRulesScript extends Script { 
    def shipppingRules =[] 

    def shipping(String name, Closure c) { 
     def newRules=new ShippingRules(name) 
     shipppingRules << newRules 
     c.delegate=newRules 
     c() 
    } 
} 

def cfg= new CompilerConfiguration(
    scriptBaseClass:ShippingRulesScript.name 
) 
Script dslScript = new GroovyShell(cfg).parse(new File("Standard")) 

dslScript.run() 

예라고 가정 선적 할 자본을 잃고 콜론 대신 과제를 사용하십시오.

그런 다음 나중에 dslScript shippingRules 변수에서 배송 규칙을 검색 할 수 있습니다.

면책 조항 : 내가 지금 내 코드를 테스트 할 수 없습니다, 그래서 코드에 오타가있을 수 있습니다,하지만 당신은 일반적인 생각을 : 당신이 당신의 스크립트에 규칙과 속성을 제공하는 기본 클래스를 사용합니다.

+0

감사합니다. ExpandoMetaClass를 사용하여 전역 함수를 스크립트의 환경에 연결하는 것에 대해서만 알고 있었지만이 추상 클래스 확장은 훨씬 더 쉽고 이해하기 쉽습니다. – NagyI

0

Google+에서 비슷한 질문을했습니다. here을 참조하십시오.
요약은 다음과 같습니다. 생성자 (ctors) 및 함수 매개 변수에 대해서만 맵 구문을 사용할 수 있습니다.

흥미로운 점은 예외가 발생하지 않는다는 것입니다.