Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-7094

Semantic of access super fields is not consistent: super.@field == super.field

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • 4.0.0-alpha-1, 3.0.5, 2.5.13
    • None
    • None

    Description

      Hello.

      Operators page describe Javafield(.@) operator.

      Super.@ has been found in experiments and then in comments: http://jira.codehaus.org/browse/GROOVY-5949?focusedCommentId=328216&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-328216 and does not reflected in documentation.

      Groovy beans make also differences by accessing fields within or outside class:

      If you access a property from within the class the property is defined in at compile time with implicit or explicit this (for example this.foo, or simply foo), Groovy will access the field directly instead of going though the getter and setter.

      Let's try that code:

      class A{
          def some = '_A.some field direct_';
      
          def getSome(){
              '-A.getSome()-'
          }
          
          def test(){
              println "this=$this"
              println "super=$super"
              println "this.some: ${this.some}"
              println "this.@some: ${this.@some}"
          }
      }
      
      class B extends A{
          def getSome(){
              '-B.getSome()-'
          }
          
          def test(){
              println "this=$this"
              println "super=$super"
              println "this.some: ${this.some}"
      //        println "this.@some: ${this.@some}" //groovy.lang.MissingFieldException: No such field: some for class: B
              println "super.some: ${super.some}"
              println "super.@some: ${super.@some}"
              println "super.getSome(): ${super.getSome()}"
          }
      }
      
      A a = new A();
      B b = new B();
      
      println 'From A:'
      a.test()
      println "outside class: a.some: ${a.some}"
      println "outside class: a.@some: ${a.@some}"
      
      println 'From B:'
      b.test()
      println "outside class: b.some: ${b.some}"
      //println "outside class: b.@some: ${b.@some}" // groovy.lang.MissingFieldException: No such field: some for class: B
      

      Give next output:

      From A:
      this=A@3179e3cb
      super=A@3179e3cb
      this.some: _A.some field direct_
      this.@some: _A.some field direct_
      outside class: a.some: -A.getSome()-
      outside class: a.@some: _A.some field direct_
      From B:
      this=B@538f7b25
      super=B@538f7b25
      this.some: -B.getSome()-
      super.some: -A.getSome()-
      super.@some: -A.getSome()-
      super.getSome(): -A.getSome()-
      outside class: b.some: -B.getSome()-
      

      Some observations:

      • this and super refer to one object in base and child class.
      • Refer this.@some in child class (and outside class: b.@some) throw "MissingFieldException: No such field" as seems correct because B has not field some, but A.
      • "super.@some" does not throw exception in child class but goes through A setter getSome() exactly as "super.some".

      My expectation what "super.@some" should refer parent class field directly.
      But at least documentations needs to be updated for more clear describe that for case of inheritance and access rules with/within parent/childs classes.

      Also questionable but may be b.@some should work too? Off course java does not inherit fields and properties, only methods, but in case of generated public getters inherited it is really assumed in groovy, is not?

      Attachments

        Activity

          People

            emilles Eric Milles
            hubbitus Pavel Alexeev
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: