groovy
  1. groovy
  2. GROOVY-2951

Cannot override instance methodMissing() in ExpandoMetaClass

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.5.6, 1.6-beta-1
    • Fix Version/s: 1.7-beta-1
    • Component/s: None
    • Labels:
      None
    • Testcase included:
      yes
    • Number of attachments :
      3

      Description

      It is not possible to provide an instance-level methodMissing() implementation for a class via ExpandoMetaClass. Note that it is possible to do this for the static version of the method. See the attached test case.

      1. 2951Patch_v17x.txt
        4 kB
        Roshan Dawrani
      2. MethodMissingTestCase.groovy
        0.4 kB
        Peter Ledbrook

        Activity

        Hide
        Roshan Dawrani added a comment -

        Hi,
        I am attaching patches for branches 1.5.x and 1.6.x that resolved this issue and an accompanying test case.

        There was no issue with specifying methodMissing at instance level. Issue was related to how a method is identified internally as the special MethodMissing method.

        A method gets registered as the special missingMethod only if its name is "methodMissing" and it takes 2 parameters - 1st String and 2nd Object.

        In the following code, although the name is methodMissing, the types of parameters are [Object, Object] and hence it does not get registered as methodMissing at EMC level:

        TestClass.metaClass.methodMissing = { method, args ->
            return method
        }
        

        So, one work around is to use the syntax:

        TestClass.metaClass.methodMissing = { String method, args ->
            return method
        }
        

        Now "new TestClass().test()" correctly invokes missingMethod().

        However, with the patch supplied, even if method name's type is not explicitly specified as String, it still gets handled and methodMissing works as expected.

        rgds,
        Roshan

        Show
        Roshan Dawrani added a comment - Hi, I am attaching patches for branches 1.5.x and 1.6.x that resolved this issue and an accompanying test case. There was no issue with specifying methodMissing at instance level. Issue was related to how a method is identified internally as the special MethodMissing method. A method gets registered as the special missingMethod only if its name is "methodMissing" and it takes 2 parameters - 1st String and 2nd Object. In the following code, although the name is methodMissing, the types of parameters are [Object, Object] and hence it does not get registered as methodMissing at EMC level: TestClass.metaClass.methodMissing = { method, args -> return method } So, one work around is to use the syntax: TestClass.metaClass.methodMissing = { String method, args -> return method } Now "new TestClass().test()" correctly invokes missingMethod(). However, with the patch supplied, even if method name's type is not explicitly specified as String, it still gets handled and methodMissing works as expected. rgds, Roshan
        Hide
        Roshan Dawrani added a comment -

        Attaching the patch for 1.7.x as the issue was found there as well.

        rgds,
        Roshan

        Show
        Roshan Dawrani added a comment - Attaching the patch for 1.7.x as the issue was found there as well. rgds, Roshan
        Hide
        blackdrag blackdrag added a comment -

        Since the solution is to use the String type for the name parameter I reduce the priority of this bug to minor. It is an annoying gotcha, which is the reason I did not close it as "won't fix". I also think that this might influence meta programming in an unexpected way, so 1.5.x and 1.6.x are for now out of the picture for this bug. I think it should be fixed for 1.7 only. If we have more experience with it we can still backport it.

        Show
        blackdrag blackdrag added a comment - Since the solution is to use the String type for the name parameter I reduce the priority of this bug to minor. It is an annoying gotcha, which is the reason I did not close it as "won't fix". I also think that this might influence meta programming in an unexpected way, so 1.5.x and 1.6.x are for now out of the picture for this bug. I think it should be fixed for 1.7 only. If we have more experience with it we can still backport it.
        Hide
        Roshan Dawrani added a comment -

        So, I can just fix it on 1.7 and mark it as Fixed? Or should its status be left open?

        Show
        Roshan Dawrani added a comment - So, I can just fix it on 1.7 and mark it as Fixed? Or should its status be left open?
        Hide
        blackdrag blackdrag added a comment -

        apply the patch and mark it as fixed. I prefer followup issues.

        Show
        blackdrag blackdrag added a comment - apply the patch and mark it as fixed. I prefer followup issues.
        Hide
        Roshan Dawrani added a comment -

        Fixed in v1.7.

        Show
        Roshan Dawrani added a comment - Fixed in v1.7.

          People

          • Assignee:
            Roshan Dawrani
            Reporter:
            Peter Ledbrook
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: