1. Groovy
  2. GROOVY-2310

ExpandoMetaClass does not offer a consistent way to retrieve and invoke overloaded methods


    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.1-rc-2
    • Fix Version/s: 2.x
    • Component/s: groovy-runtime
    • Labels:


      As discussed with Graeme, take a Grails plugin for example that might supply a proxy "render" method for controllers, that checks for certain parameters and if present does something, else defers to the pre-existing render() method. There are several default render(...) variants overloaded, but this plugin replaces only a specific one:

      def oldRender = controllerClass.metaClass.render
      controllerClass.metaClass.render = { Map m, Closure c -> 
        if (!something) oldRender(m, c)

      This may work sometimes if the render method retrieved from the EMC is the one that takes Map, Closure. Sometimes it may not be though, and then you get method invocation errors when it tries to pass in the Map and Closure.

      Currently the workaround is to use metaClass.getMetaMethod( name, argTypes) but this gives you a different invocation paradigm - i.e. you must call invoke() on the MetaMethod.

      A couple of features then offer themselves as part or whole solutions:

      1. Make MetaMethod support call()/doCall() as well as invoke()
      2. Make EMC's methodMissing return a new MultiMetaMethodProxy object that, when call() is invoked, automatically determines which overloaded method to invoke. This could be dangerous, needs further assessment. This is the most elegant approach in my opinion, but I don't believe anywhere else in groovy treats all overloaded forms of a method as a "single" method and as such the terminology may not work. The concept is great, but maybe Groovy needs a new term for this, such as "Message" as in other OO languages. i.e. a MetaMessage is some invokation you can perform on an object using but the exact method that will be called is dependent on the args, i.e. it knows about all the possible MetaMethods.
      3. Add a new findMethod(name, argTypes) that returns a method reference instead of MetaMethod.


        Marc Palmer created issue -
        Guillaume Delcroix made changes -
        Field Original Value New Value
        Assignee Graeme Rocher [ graemerocher ]
        Guillaume Delcroix made changes -
        Fix Version/s 1.6 [ 13832 ]
        Fix Version/s 1.7 [ 14014 ]
        Guillaume Delcroix made changes -
        Fix Version/s 1.7-beta-x [ 15538 ]
        Fix Version/s 1.7-beta-1 [ 14014 ]
        Jochen Theodorou made changes -
        Fix Version/s 2.x [ 17013 ]
        Fix Version/s 1.7.x [ 15538 ]
        Fix Version/s 1.8.x [ 15750 ]
        Pascal Schumacher made changes -
        Assignee Graeme Rocher [ graemerocher ]
        Jochen Theodorou made changes -
        Fix Version/s 1.8.x [ 15750 ]
        Jochen Theodorou made changes -
        Component/s groovy-runtime [ 16250 ]
        Mark Thomas made changes -
        Project Import Sun Apr 05 13:32:57 UTC 2015 [ 1428240777691 ]
        Mark Thomas made changes -
        Workflow jira [ 12731378 ] Default workflow, editable Closed status [ 12743312 ]
        Mark Thomas made changes -
        Project Import Mon Apr 06 02:11:23 UTC 2015 [ 1428286283443 ]
        Mark Thomas made changes -
        Workflow jira [ 12974106 ] Default workflow, editable Closed status [ 12981265 ]


          • Assignee:
            Marc Palmer
          • Votes:
            0 Vote for this issue
            2 Start watching this issue


            • Created: