2012-05-24 2 views
2

Я хочу реализовать «активный» флаг для правил в моем DSL. Вот как я хотел, чтобы это выглядело как:Groovy DSL: настройка свойств в закрытии

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

    rules { 
     ... define rules here 
    } 
} 

Вот как я получил все работает следующие несколько учебников:

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

Это все прекрасно работает без жалоб но как я могу получить доступ к «активному» или «описанию»?

Что вообще делает этот синтаксис? Это похоже на присвоение карты, но ее нет. Или компилятор groovy относится к нему как к неполному тернарному оператору?

ответ

4

Могу ли я предложить небольшое изменение в вашей 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() 

Маршрутизатор DSL должен быть изменен на это:

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

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

    rules { 
     ... define rules here 
    } 
} 

Т.е. потерять капитал до отгрузки и использовать назначения вместо двоеточий.

После этого вы сможете получить правила доставки из переменной dvlScript shippingRules.

отказ от ответственности: Я не могу проверить свой код прямо сейчас, поэтому могут возникнуть некоторые опечатки в коде, но вы получите общую идею: используйте базовый класс, в котором вы указываете свои правила и свойства для своего сценария.

+0

Спасибо за это! Я знал только об использовании ExpandoMetaClass для присоединения глобальных функций к среде Script, но это расширение абстрактного класса намного проще и понятно. – NagyI

0

Я задал аналогичный вопрос в Google+, см. here.
Резюме: вы можете использовать синтаксис карты только для конструкторов (ctors) и в качестве параметров функции.

Интересно, что это не исключение.

Смежные вопросы