Details
-
Improvement
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
Description
The property semantics for map-based types was recently updated (see GROOVY-11367). testRead3() and testRead4() demonstrate the desired outcome: public members (except isEmpty() and getClass()) then map get/put.
testRead1() and testRead2() demonstrate the differing semantics for this references: accessible fields and public methods then map get/put. Why the difference between fields and methods? Also there are differences between dynamic and static compilation modes (as noted).
import groovy.transform.* class M implements Map<String,String> { @Delegate Map<String,String> map = [:].withDefault{ 'entry' } public a = 'field' protected b = 'field' @PackageScope c = 'field' private d = 'field' Closure e = { 'called' } public getF() { 'getter' } protected getG() { 'getter' } @PackageScope getH() { 'getter' } private getI() { 'getter' } public void setF(f) { 'setter' } protected void setG(g) { 'setter' } @PackageScope void setH(h) { 'setter' } private void setI(i) { 'setter' } void testRead1() { println a // field println b // field println c // field println d // field println e // proper println f // getter println g // entry (dynamic) or getter (static) println h // entry (dynamic) or getter (static) println i // entry (dynamic) or getter (static) println j // entry println empty // entry (dynamic) or isser (static) println metaClass // field (dynamic) or getter (static) println ""; {-> println a // field println b // entry println c // entry println d // entry println e // proper println f // getter println g // entry println h // entry println i // entry println j // entry println empty // entry println metaClass // getter (of Closure) }() } void testRead2() { println this.a // field println this.b // field println this.c // field println this.d // field println this.e // proper println this.f // getter println this.g // entry (dynamic) or getter (static) println this.h // entry (dynamic) or getter (static) println this.i // entry (dynamic) or getter (static) println this.j // entry println this.empty // entry (dynamic) or isser (static) println this.class // entry (dynamic) or getter (static) println this.metaClass // field (dynamic) or getter (static) println ""; {-> println this.a // field println this.b // entry (dynamic) or field (static) println this.c // entry (dynamic) or field (static) println this.d // entry (dynamic) or field (static) println this.e // proper println this.f // getter println this.g // entry (dynamic) or getter (static) println this.h // entry (dynamic) or getter (static) println this.i // entry (dynamic) or getter (static) println this.j // entry println this.empty // entry (dynamic) or isser (static) println this.class // entry (dynamic) or getter (static) println this.metaClass // getter }() } void testRead3() { def that = this println that.a // field println that.b // entry println that.c // entry println that.d // entry println that.e // proper println that.f // getter println that.g // entry println that.h // entry println that.i // entry println that.j // entry println that.empty // entry println that.class // entry println that.metaClass // getter println ""; {-> println that.a // field println that.b // entry println that.c // entry println that.d // entry println that.e // proper println that.f // getter println that.g // entry println that.h // entry println that.i // entry println that.j // entry println that.empty // entry println that.class // entry println that.metaClass // getter }() } void testRead4() { this.with { println a // field println b // entry println c // entry println d // entry println e // proper println f // getter println g // entry println h // entry println i // entry println j // entry println empty // entry println metaClass // getter (of Closure) } def that = this; println "" that.with { println a // field println b // entry println c // entry println d // entry println e // proper println f // getter println g // entry println h // entry println i // entry println j // entry println empty // entry println metaClass // getter (of Closure) } } }
Attachments
Issue Links
- is related to
-
GROOVY-8555 The private keyword of an instance variable is causing a behavior change in a map class
- Closed
-
GROOVY-11367 property semantics of map-based types
- Closed