views:

172

answers:

1

I have several categories that I use in my Grails plugin. e.g.,

class Foo {
    static foo(ClassA a,Object someArg) { ... }
    static bar(ClassB b,Object... someArgs) { ... }
}

I'm looking for the best way to add these methods to the meta-classes so that I don't have to use the category classes and can just invoke them as instance methods. e.g.,

aInstance.foo(someArg)

bInstance.bar(someArgs)

Is there a Groovy/Grails class or method that will help me do this or am I stuck iterating through the methods and adding them all myself?

+2  A: 

In Groovy 1.6 a much simpler mechanism for using categories/mixins was introduced. Previously the methods of a category class had to be declared static, and the first parameter indicates which class of objects they could be applied to (as in your Foo class above).

I find this somewhat awkward because once the methods of the category are "mixed in" to the target class they are non-static, but in the category class they are static.

Anyway, since Groovy 1.6 you can do this instead

// Define the category
class MyCategory {
  void doIt() {
    println "done"
  }

  void doIt2() {
    println "done2"
  }
}

// Mix the category into the target class
@Mixin (MyCategory)
class MyClass {
   void callMixin() {
     doIt()
   }
}

// Test that it works
def obj = new MyClass()
obj.callMixin()

A few other features are available. If you want to restrict the classes that the category can be applied to, use the @Category annotation. For example, if you only want to apply MyCategory to MyClass (or it's subclasses), define it as:

@Category(MyClass)
class MyCategory {
  // Implementation omitted
}

Instead of mixing the categories in at compile-time using @Mixin (as above), you can mix them in at runtime instead using:

MyClass.mixin MyCategory

In you're using Grails, Bootstrap.groovy is a place where you might do this.

Don