14

I'm just playing with the metaclass programming in Groovy. But suddenly I was facing a little problem which I just could not get working...

Here is the simple script:

// define simple closure
def printValueClosure = {
 println "The value is: '$delegate'"
}

String.metaClass.printValueClosure = printValueClosure

// works fine
'variable A'.printValueClosure()



// define as method
def printValueMethod(String s){
 println "The value is: '$s'"
}

// how to do this!?
String.metaClass.printValueMethod = this.&printValueMethod(delegate)

'variable B'.printValueMethod()

Is it possible to use the method but set the first parameter to the calling object? using delegate seems not to work... The assignment of methods which do not reference the caller is no problem. Does currying work here?

Thanks, Ingo

ataylor
  • 64,891
  • 24
  • 161
  • 189
Leikingo
  • 890
  • 3
  • 10
  • 23

1 Answers1

19

The simplest way to accomplish this is to wrap the method in a closure, like so:

def printValueMethod(String s){
    println "The value is: '$s'"
}

String.metaClass.printValueMethod = { -> printValueMethod(delegate) }

assert 'variable B'.printValueMethod() == "The value is: 'variable B'"

The idomatic way to add a method without using closures would be to create a category class and mix it in like so:

class PrintValueMethodCategory {
    static def printValueMethod(String s) {
        println "The value is: '$s'"
    }
}

String.metaClass.mixin(PrintValueMethodCategory)

assert 'variable B'.printValueMethod() == "The value is: 'variable B'"

I don't think currying can help in this particular case, since you don't know the value of the delegate at the time of assignment to the metaclass.

ataylor
  • 64,891
  • 24
  • 161
  • 189
  • Nice. Thanks. Never thought of that... Is there also a convenient way to add a lot of static helper method to a class (not via category). For example Apache Commons IO FileUtils to the file class? – Leikingo Dec 10 '10 at 18:52
  • ah...your edit also answers my additional question. Thanks again. – Leikingo Dec 10 '10 at 18:54