groovy
  1. groovy
  2. GROOVY-2310

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

    Details

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

      Description

      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 MetaMessage.call(args) 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.

        Activity

        No work has yet been logged on this issue.

          People

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

            Dates

            • Created:
              Updated: