In a previous blog post we learned how to use Categories to add functionality to existing class. We had to use the use keyword to define a block in which the Category was valid. But we can also add new functionality with the @Mixin compile-time annotation or at runtime with the mixin() method (GDK extension to Class).
class Pirate {
def talk(text) {
"Aargh, walk the plank. ${text}"
}
}
// Compile time mixin to Talk class. This add all
// methods from Pirate to Talk.
@Mixin(Pirate)
class Talk {}
assert 'Aargh, walk the plank. Give me a bottle of rum.' == new Talk().talk("Give me a bottle of rum.")
import org.apache.commons.lang.StringUtils
class Parrot {
static String speak(String text) {
/Parrot says "$text"/
}
}
// Runtime mixin on String class.
// mixin() is a GDK extension to Class.
String.mixin Parrot, StringUtils
assert 'Parrot says "mrhaki"' == 'mrhaki'.speak()
assert 'Groovy is so much...' == 'Groovy is so much fun.'.abbreviate(20) // StringUtils mixin.
4 comments:
@Mixin isn't a compile-time modifier. Its also dynamic, meaning that any java code you write can NOT access the mixin nature. Believe me, I tried.
@Goldfish: thank you for your comment. I haven't tried it to call the class from Java code.
Does anyone know if this works for Grails GORM objects?
I've tried to add behavior to GORM domain objects and it doesn't seem to work.
Nice trick, read most of your posts about Groovy, love it. Thanks for the good work.
Post a Comment