2012-10-31 37 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: 
     ... 
    } 

我的问题是如何有人可以得出这个限制和使用自定义DSL中的10个属性名称?

回答

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

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

1

简单的答案是否定的,你不能。 'owner'是Groovy中的保留关键字,因此根据定义不能用作任意符号。即使有办法解决这个问题,但使用与语言实现不冲突的名称会更好 - 这在Groovy中尤其如此,它始终承诺完全重新设计其MOP,这意味着你实施的任何黑客可能会在未来的版本中停止工作。

也许这个问题会更有意义,如果你解释了为什么你愿意提供赏金和寻找绕开这个问题的方法,而不仅仅是改变名称到不同的地方,并完全避免这个问题。保留的符号是一种语言的一个非常基本的限制,有试图解决它们似乎是非常不明智的。