2

単純な 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

問題は、Groovy自体ownerの予約済みプロパティであり、 Groovy の実装により、値をデリゲートからのカスタム値に置き換えるのに役立つオプションがないことです。ClosureresolveStrategyownergetPropertyClosure

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 でプロパティ名を使用できるかということです。

4

2 に答える 2

1

簡単な答えはノーです、あなたはできません。'owner'はGroovyで予約されているキーワードであるため、定義上、任意の記号として使用することはできません。これを回避する方法がある場合でも、言語の実装と競合しない名前を使用する方がはるかに優れています。これは、MOPを完全に再設計することを約束し続けるGroovyに特に当てはまります。実装するハックは、将来のバージョンでは機能しなくなる可能性があります。

名前を別の名前に変更して問題を完全に回避するのではなく、賞金を提供してこの問題をハッキングする方法を探す理由を説明した場合、おそらく質問はより理にかなっています。予約された記号は言語のかなり基本的な制限であり、それらを回避しようとすることは非常に賢明ではないようです。

于 2012-11-05T01:29:07.570 に答える
1

これはちょっとしたハックですが、Groovy のソースを変更せずに、必要なものが得られるはずです。

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

    def dslDelegate = new MyDslDelegate(owner:  'IncCorp', payee: 'TheBoss')
    clonedCode.@owner = dslDelegate.owner
    clonedCode.resolveStrategy = Closure.DELEGATE_ONLY

    clonedCode.delegate = dslDelegate
    clonedCode.call()
}

参考: 閉鎖の所有者を変更することは可能ですか?

于 2012-11-02T23:53:47.253 に答える