2012-10-31 1 views
2

Давайте рассмотрим простой Groovy DSLИспользуйте 'владелец' в Groovy DSL

execute { 
    sendNotification owner 
    sendNotification payee 
} 

Реализация выполнения является

public static void execute(Closure dslCode) { 
    Closure clonedCode = dslCode.clone() 
    def dslDelegate = new MyDslDelegate(owner: 'IncCorp', payee: 'TheBoss') 

    clonedCode.delegate = dslDelegate 
    clonedCode.call() 
} 

и пользовательский делегат

public static class MyDslDelegate { 
    def owner 
    def payee 

    void sendNotification(to) { 
     println "Notification sent to $to" 
    } 
} 

Ожидаемый результат от эксплуатации execute Блок:

Notification sent to IncCorp 
Notification sent to TheBoss 

фактического один

Notification sent to class package.OwnerClassName 
Notification sent to TheBoss 

Проблема заключается в том owner является зарезервированным свойством в Groovy Closure сами и не resolveStrategy вариантов не помогают заменить owner значения с таможенной стоимостью от делегата благодаря Groovy getProperty реализации для Closure

public Object getProperty(final String property) { 
    if ("delegate".equals(property)) { 
     return getDelegate(); 
    } else if ("owner".equals(property)) { 
     return getOwner(); 
    ... 
    } else { 
     switch(resolveStrategy) { 
      case DELEGATE_FIRST: 
     ... 
    } 

Мой вопрос заключается в том, как кто-нибудь может исход это ограничение и использовать owner в пользовательском DSL?

ответ

1

Это немного рубить, но это должно получить, что вы хотите, не изменяя Groovy источник:

public static void execute(Closure dslCode) { 
    Closure clonedCode = dslCode.clone() 

    def dslDelegate = new MyDslDelegate(owner: 'IncCorp', payee: 'TheBoss') 
    [email protected] = dslDelegate.owner 
    clonedCode.resolveStrategy = Closure.DELEGATE_ONLY 

    clonedCode.delegate = dslDelegate 
    clonedCode.call() 
} 

Ref: Is it possible to change the owner of a closure?

1

Простой ответ: нет, вы не можете , «владелец» является зарезервированным ключевым словом в Groovy, и поэтому по определению нельзя использовать в качестве произвольного символа. Даже если есть способ взломать это, вам гораздо лучше просто использовать имя, которое не противоречит реализации языка - это особенно верно в Groovy, что обещает полностью перепроектировать его MOP, что означает что любой взломанный вами инструмент может прекратить работу в будущих версиях.

Возможно, вопрос будет иметь смысл, если вы объясните, почему вы готовы предложить щедрость и искать способ взломать эту проблему, а не просто менять имя на что-то другое и полностью избегать проблемы. Зарезервированные символы являются довольно фундаментальным ограничением языка, и когда-либо пытаться обойти их кажется очень неразумным.

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