groovy

今度はgroovyを試してみる。installはtar.gzを展開してPATHとGROOVY_HOMEを通すだけ。$GROOVY_HOME/bin/にはインタプリタのgroovy、対話的シェル(Rubyirb)のgroovysh、そして何とコンパイラのgroovycなどが置かれている。groovyshは、実行するときにいちいち"execute"を入れなきゃいけないのは何とか我慢するとしても、コマンドライン編集が使えないのが痛い。痛いが、JRubyよりはましか?

hao% groovysh
Let's get Groovy!
================
Version: 1.0-RC-01 JVM: 1.6.0-b105
Type 'exit' to terminate the shell
Type 'help' for command help
Type 'go' to execute the statements

groovy> for (i=0; i<10; i++) {
groovy> println i
groovy> }
groovy> execute
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, CommandLine.groovy: 1: For statement contains unexpected tokens. Possible attempt to use unsupported Java-style for loop. at line: 1 column: 1. File: CommandLine.groovy @ line 1, column 1.
1 error

いきなり何も考えずに打ち込んだところ、Java-styleのforは知らん、と言われる。Java-styleってわかってるなら何とかしてくれてもよさそうなもんだが。正しくは、RubyJavaの混合みたいな感じ。

groovy> for (i in 1..10) {
groovy> println i
groovy> }
groovy> execute
1
2
3
4
5
6
7
8
9
10

===> null

Rubyだとiteratorのおかげでforなんか使うことはほとんど無いのだが、これもちゃんと用意されてる。

groovy> a = [1,2,3]
groovy> a.each {
groovy> println it
groovy> }
groovy> execute
1
2
3

===> null

変数名が"it"決め打ちじゃHashの時困らないか? と思ったら、

groovy> h = ['a':123,'b':234]
groovy> h.each {
groovy> println it.key
groovy> println it.value
groovy> }
groovy> execute
b
234
a
123

===> null

Ruby

h.each do |k,v|

の方がエレガントではないだろうか?変数名は、

h.each {i |
println i.key
println i.value
}

のように明示もできる。と言うか、省略値が"it"なのね。
JRubyの時にやった、しょぼしょぼベンチマークをやってみる。

hao% cat test.groovy
s = 'abcdefg12345abcdefg12345'
for (i in 1..10000) {
s.matches('^abcde')
s.matches('^.*12345.*$')
s.matches('^.*abcde.*$')
}
hao% time groovy test.groovy
groovy test.groovy  1.07s user 0.06s system 109% cpu 1.026 total

Rubyよりかなり遅いが、インタプリタの起動(Javaだから...)を考えると頑張ってる方か? ループの回数を10倍にしてみたら

ruby ./test.rb  2.08s user 0.06s system 98% cpu 2.184 total
groovy test.groovy  2.11s user 0.07s system 104% cpu 2.072 total

逆転してしまった。さらにコンパイルしてclassに落とすことも可能。

hao% groovyc test.groovy
hao% time java test
java test  1.71s user 0.06s system 101% cpu 1.735 total

これはちょっと期待はずれだが、逆にスクリプトとしての実行が充分速いわけで、カテゴリとして単純にLLに分類してはいけないのかも知れない。groovyshのexecuteもそのあたりに起因しているような。
とは言え、使い勝手としてはRubyPerlと変わらないし、機能的には、Java側のクラスライブラリとして嫌と言うほど揃ってるわけで、さらに自分でJava書けばclasspath通すだけで機能追加できるし、無敵か? 何で普及しない?