この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
Groovyにはメタプログラミング向けの特徴が多数あります。Categoriesはその特徴のひとつであり、限定された範囲で一時的に既存クラスにメソッドの追加を行うことができます。
Category Classを使う
試しに TimeCategory
と呼ばれるCategory Classを使ってメソッドの追加を行ってみます。
use(TimeCategory) {
println 1.minute.from.now
println 10.hours.ago
def someDate = new Date()
println someDate - 3.months
}
use
メソッドは引数にCategory Classとクロージャを受け取ります。Category Classには追加したいメソッドが記述されており、以降のクロージャではそれらのメソッドが対象クラスに追加されます。
上記の例ではInteger
にgetMinute
やgetHours
、Date
にminus
などのメソッドが追加されています(それぞれのメソッドはフィールドアクセスや演算子オーバーロードされています)。
Category Classを作る
Category Classを自作したい場合は、通常のクラスと同様に宣言し、追加したいメソッドは全てstatic method
として実装する必要があります。またメソッドの第一引数(self
)の型がメソッドの追加対象クラスを表します。
例としてStringに回文判定をするメソッドを追加するCategory Classを実装してみます。
class PalindromeCategory {
static boolean isPalindrome(String self){
return self == self.reverse()
}
}
use
を使って拡張すると文字列に対してisPalindrome
が使えるようになります。
use(PalindromeCategory){
assert "abcba".isParindrome() == true
assert "nishioishin".isParindrome() == false
}
@Category
アノテーションを使ってCategory Classを表現することもできます。この場合、アノテーションに対象クラスを指定することでメソッドの第一引数を省略することができます。またメソッドもstatic
ではなく通常のメソッドとして宣言できます。
@Category(String)
class PalindromeCategory {
boolean isParindrome(){
return this == this.reverse()
}
}