2012-04-26 6 views
6

Groovy scheint ein sehr unangenehmes Verhalten zu haben, das mit "Groovy Beans" und Verschlüssen zusammenhängt, die dazu führen können, dass es unter bestimmten Umständen lokale Variablen maskiert.Starker Konflikt zwischen automatischem Getter, lokalen Variablen und Closures?

Ist das bekannte Verhalten und gibt es irgendwo Dokumentation, die Details dieses Zeug? Ich vergeudete viel Zeit, um herauszufinden, was nicht funktionierte ...

den folgenden Code vor:

class TestClass { 

    def doIt(Closure closure) { 
     closure.setDelegate(this) 
     closure.call() 
    } 

    def getRevision() { 
     return "testclass revision" 
    } 
} 

def testIt() { 
    def revision = "testit revision" 

    println "1: " + revision + " (expect: testit)" 

    TestClass tester = new TestClass() 
    tester.doIt { 
     println "2: " + getRevision() + " (expect: testclass)" 
    } 

    println "3: " + revision + " (expect: testit)" 

    tester.doIt { 
     println "4: " + revision + " (expect: testit)" 
     revision = getRevision() 
     println "5: " + revision + " (expect: testclass)" 
     println "6: ${getRevision()} (expect: testclass)" 
     println "7: " + getRevision() + " (expect: testclass)" 
    } 

    // expect to have been set to testclass value in previous closure 
    println "8: " + revision + " (expect: testclass)" 

    tester.doIt { 
     println "9: ${getRevision()} (expect: testclass)" 
     println "10: " + getRevision() + " (expect: testclass)" 
    } 

    println "11: " + revision + " (expect: testclass)" 
} 

testIt() 

Ausführen dieses Code erzeugt die folgende Ausgabe:

1: testit revision (expect: testit) 
2: testclass revision (expect: testclass) 
3: testit revision (expect: testit) 
4: testit revision (expect: testit) 
5: testit revision (expect: testclass) 
6: testit revision (expect: testclass) 
7: testit revision (expect: testclass) 
8: testit revision (expect: testclass) 
9: testclass revision (expect: testclass) 
10: testclass revision (expect: testclass) 
11: testit revision (expect: testclass) 

Meine Hauptproblem ist mit 5/6/7. Es scheint, dass die lokale revision Variable innerhalb der Schließung einfach die getRevision() Methode im Delegaten verbirgt und sie durch eine automatisch erzeugte getRevision() Bean ersetzt, die der revision "Eigenschaft" entspricht. Wenn ich die Variable revision nicht verwende, rufen Aufrufe von getRevision() dieses Bean-Verhalten nicht auf.

Jeder Einblick oder Links zur Dokumentation wäre willkommen!

Antwort

1

Groovy Verschlüsse have a resolveStrategy property, die zur Steuerung der Auflösungsreihenfolge verwendet werden können. Die Standardstrategie besteht darin, die Eigenschaft vom Objekt "Owning" aus zu suchen und nur dann, wenn sie dort nicht gefunden wird, um den Delegaten zu verwenden. Ich glaube, dass die Einstellung DELEGATE_FIRST das Verhalten erhalten wird, das Sie erwarten.

+0

Danke für die Antwort. Ich habe deinen Vorschlag ausprobiert, aber leider hat es nicht geholfen. Ich denke, das Problem ist hier zur Kompilierzeit: die Verwendung von 'revision' und' getRevision() 'innerhalb der Schließung bringt den groovigen Compiler dazu, ein Getter für die 'revision'-Variable zu generieren, die dann die Version des Delegierten verbirgt. –

Verwandte Themen