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

Using metaClass to override methods in class hierarchy does not work as expected

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.8-beta-1
    • None
    • groovy-runtime
    • None
    • Windows XP

    Description

      I've found some strange behaviour when dynamically overriding methods that are called in a class hierarchy, which I think might be a bug. The problem is that when I override a method on a subclass, code in the superclass still calls the original method (note all classes are Groovy ones, I know this wouldn't work with a Java class hierarchy).

      I've isolated it to this sample code:

          class BaseClass {
              def baseClassMethod() {
                  println "BaseClass.baseClassMethod()"
                  internalMethod()
              }
              def internalMethod() {
                 println "    BaseClass.internalMethod()"
              }
          }
      
          class SubClass extends BaseClass {
              def subClassMethod() {
                  println "SubClass.subClassMethod()"
                  internalMethod()
              }
          }
      
          def subClass = new SubClass()
          subClass.metaClass.internalMethod = { -> println ("    (dynamic).internalMethod()")}
          subClass.baseClassMethod()
          subClass.subClassMethod()
      

      ...which gives me the following output...

      BaseClass.baseClassMethod()
      BaseClass.internalMethod()
      SubClass.subClassMethod()
      (dynamic).internalMethod()

      I would have expected that the dynamic version of internalMethod() would be called both times, given that Groovy has dynamic method dispatching.

      Some discussion of this issue took place on the mailing list: http://old.nabble.com/Problems-using-metaClass-to-override-methods-in-class-hierarchy-td26743895.html#a26743895

      The suggestion is that the CallSiteArray.createCallCurrentSite(...) method could check whether the receiver is a sub class of the sender class.

      Attachments

        1. MetaclassOverrideTest.groovy
          0.9 kB
          Jason Griffith

        Activity

          People

            Unassigned Unassigned
            alexmcmanus Alex McManus
            Votes:
            7 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

              Created:
              Updated: