2012年5月29日

Groovy Category(Mixin)初探

今天參加了第四屆 Scala Taipei 聚會,由Walter主講Typeclass in Scala;現場展示了traits與implicit功能,展現了物件的type-safe及subtyping(polymorphism)威力,並可隨心所欲的創造不同subtype的object;真是收獲良多!
於是乎讓我連想到了在很多領域都具有相同的功能:mix-in概念,諸如:Ruby的module、Objective-C的Category。當然,身為Groovy的使用者,也不能放過號稱dynamic language的Groovy。

在Groovy中使用了Category這個名稱,實作上則分成兩種典型:
use() method用在class的static method,程式寫作上非常直觀、簡單;但要注意的是,若class在另一個groovy file時,要利用dock type;
也就是不要宣告型別,否則會發生 Caught: groovy.lang.MissingMethodException: No signature of method: ...錯誤。
所以要如下範例:
// current file
def config = new ConfigSlurper().parse(new File('/tmp/my.properties').toURI().toURL())

use( MyCategory ) {
 config.append()
}


// another file
import groovy.util.ConfigObject

class MyCategory {
 static def append(conf) {
  conf.params << [YEAR: '2012', MONTH: '05', DAY: '29']
 }
}
mixin() method則用在instance method上;但groovy script的實作上與groovy class有些不同;因為每個script有各自的class loader,所以使用到別的script的method時,要先載入該script(Load script from groovy script)。如下所示:
// current file
def script = new GroovyScriptEngine( 'src/groovy' ).with {
 loadScriptByName( 'MyCategory.groovy' )
}

this.metaClass.mixin script

def config = new ConfigSlurper().parse(new File('/tmp/my.properties').toURI().toURL())
append(config)


// another file
import groovy.util.ConfigObject

class MyCategory {
 def append(conf) {
  conf.params << [YEAR: '2012', MONTH: '05', DAY: '29']
 }
}

沒有留言: