もうGroovyなライブラリは、Grapeを使うのがアタリマエですよね。そうですよね。
というわけで、2009/12/04にTwitterで0.9-beta1がでたよ!というTweetをみかけたので、さっそくGrapeで試してみました。
// Fibonacci def fib = { n -> return (n == 0) ? 1 : (n == 1) ? 1 : call(n - 1) + call(n - 2) } @Grab("org.codehaus.gpars:gpars:0.9-beta-1") import groovyx.gpars.actor.Actor import static groovyx.gpars.actor.Actors.actor def list = [3, 10, 15, 2, 5] def calc = actor { def count = 1 loop { react { map -> println "fib(${map.num}): ${map.result}" reply() count++ if (count > list.size()) stop() } } } list.each { num -> actor { def result = fib(num) calc.send([num:num, result:result]) react { stop() } } } calc.join()
と、@Grabアノテーションを指定したコードを書いて、実行してみると・・・
$ groovy fib_actor.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during conversion: Error grabbing Grapes -- [unresolved dependency: org.grails#grails-docs;1.2.0.BUILD-SNAPSHOT: not found, unresolved dependency: org.jboss.netty#netty;3.1.5.GA: not found] java.lang.RuntimeException: Error grabbing Grapes -- [unresolved dependency: org.grails#grails-docs;1.2.0.BUILD-SNAPSHOT: not found, unresolved dependency: org.jboss.netty#netty;3.1.5.GA: not found] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
一部の依存ライブラリがサードパーティMavenリポジトリに入っていたため、依存性解決が失敗してしまいました。
なんということでしょう。
ということをtwitterでぼやいたら、Gparsのコミッタの@vaclav_pech氏が反応してくれました。
GparsのコミッタはNice Guyなんだぜ?
というわけで、怪しい英語は見ないふりをしつつ、http://gpars.codehaus.org/Integration にある、実はnobeans製だったりするgrapeConfig.xmlのサンプルを、そのまま$HOME/.groovy配下に格納すれば*1、それ以降は普通にGparsがGrape経由で利用できます。素敵。
ちなみに、 このサンプルコードはものすごいハイウエストな方(id:nbqx69)のブログのサンプルをベースにしてます。あしからず。
でも、groovy1.7-RC2から@GrabResolverアノテーションを使えるようになったから、grapeConfig.xmlなんてもういじる必要がなくなるんですよね。
@GrabResolverを使えば、スクリプト内で見に行くMavenリポジトリを追加できます。
// ...snip @GrabResolver(name="jboss", root="http://repository.jboss.org/maven2/") @GrabResolver(name="codehaus.snapshot", root="http://snapshots.repository.codehaus.org/") @Grab("org.codehaus.gpars:gpars:0.9-beta-1") import groovyx.gpars.actor.Actor // ...snip
と書くだけでOK.
スクリプトローカルでJarの取得元を指定できます。
$ groovy fib_actor.groovy fib(3): 3 fib(2): 2 fib(5): 8 fib(10): 89 fib(15): 987
これで、よりポータブルなスクリプトがかけますね!
素晴らしい!
ただ、Gparsについていえば、そもそも今回依存性解決に失敗したライブラリは、実行時には必要なさそうな雰囲気なので、そのうちこんな小細工はいらなくなるかもしれません。
*1:自分が手動で作ってなければデフォルトでは存在しない