Mikey
Mikey

Reputation: 4752

Groovy: variables in method names with '??' double question marks

I have this vague recollection reading about groovy that there exists a '??' sugar that can be used to make method names dynamic. I had thought this is how dynamic finders in grails are achieved, but now I'm question if it was even groovy I'm recalling. Given the example: I make a class with some methods

class GroovyExample {

  public def getThingOne(){return '1'}

  public def getThingTwo(){return '2'}

  public def getModifiedThingOne(){
    return this.modify(this.thingOne)
  }

  //  *!!!*  I want to get rid of this second modifying method    *!!!*
  public def getModifiedThingTwo(){
    return this.modify(this.thingTwo)
  }

  private def modify(def thing){
    //...
    return modifiedThing
  }

}

Is there a ?? sugar for the method name I can use to DRY it up to something like this:

class GroovyExample {

  public def getThingOne(){return '1'}

  public def getThingTwo(){return '2'}

  //  Replaced the two getModifiedXX methods with a getModified?? method I think I can do....
  public def getModified??(){
    return this.modify(this."${howeverYouReferenceTheQuestionMarks}")
  }

  private def modify(def thing){
    //...
    return modifiedThing
  }

}

The idea being I can call new GroovyExample().modifiedThingTwo and get the same answer either way with only one "modification helper method". Is this possible? What are the ?? called? (I can't google it for the life of me.) And, how do I reference the String "in" ???

Upvotes: 1

Views: 804

Answers (1)

Brian Henry
Brian Henry

Reputation: 3171

I'm not aware of that syntax, but you could implement the functionality by implementing methodMissing() per here. This is, according to that link, the initial mechanism of action of the dynamic finders you mention (although I believe there is some caching after the first hit on a method) - note the caveats at the top.

Something like this quick test might fit the bill for you:

   def methodMissing(String name, args) {
       switch (name) {
           case "getModifiedThingOne":
               return this.modify(this.thingOne)
           case "getModifiedThingTwo":
               return this.modify(this.thingTwo)              
       }
   }

Upvotes: 2

Related Questions