Groovy on コマンドプロンプト

独学なのでプログラミングの最初の関門は環境設定だった。検索しては他の人の設定を参考にさせて頂いたので私も公開しておく。現在、Groovy 1.8 リリースされたところ。

Groovy をアルゴリズムの勉強をするための動く疑似コードとして使い始めた。半年間、コマンドプロンプトで使ったのでそこで得たことを書いておく。ほとんど Groovy スクリプトで書いているので本格的なアプリケーションを作成しようとしている人は他をあたった方がいいかもしれない。参考にしているブログの人達は IntelliJ を使っていることが多いように感じる*1。このエントリの対象はコマンドプロンプトで Groovy を始めてみたい人向けということになる。内容は主に環境変数の設定の方法と groovysh の使い方である。

環境変数の設定

システムの詳細から設定する環境変数には JavaMaven ぐらいしか設定していない。
use.bat を PATH に含めてコマンドプロンプトを起動*2してから

use groovy

と入力して使用している。

use.bat

仕組みは goto で設定に飛ぶだけ。
バージョンを切り替えるため PATH の前に追加している。

@echo off

goto case_%1

:case_groovy17
  set GROOVY_HOME=%INS_DIR%\java\groovy-1.7.10
  set PATH=%GROOVY_HOME%\bin;%PATH%
  set JAVA_OPTS=-Dgroovy.source.encoding=UTF-8
  goto :case_end

:case_groovy
:case_groovy18
  set GROOVY_HOME=%INS_DIR%\java\groovy-1.8.0
  set PATH=%GROOVY_HOME%\bin;%PATH%
rem ヒープ領域を変更する場合
  set JAVA_OPTS=-Xmx1024m
rem ソースファイルの文字コード
  set JAVA_OPTS=%JAVA_OPTS% -Dgroovy.source.encoding=UTF-8
  goto :case_end

:case_end


他の言語もこの調子で rhino のような jar で起動するタイプは doskey でコマンドにしている。
昔は JVM 言語は jrunscript に入れていたが EclipseJava Library に追加されて重くなるのでやめた。

:case_rhino
  set RHINO_HOME=%INS_DIR%\java\rhino1_7R2
  doskey rhino=java -Dfile.encoding=UTF-8 -jar %RHINO_HOME%\js.jar $*
  goto :case_end
文字コード

プログラムの文字コードUTF-8 で統一している。UTF-8 で書かれたファイルが多いからだ。
UTF-8 で書かれている場合、コマンドプロンプトで Groovy をそのまま実行すると問題を起こす。
次のプログラム UTF-8 の改行文字 LF で保存して sjis で実行すれば Good-bye だ。

groovy -c sjis hello.groovy

hello.groovy

def a = 0
// コメント
if (++a == 1) println "Hello Groovy"
if (a == 0)   println "Good-bye Groovy"

エラーや間違いとわかるときはいいほうで微妙な判定をすり抜けられると気づくのに時間がかかる。バグと思ってしまうこともあるかもしれない。理由はコメントに何を書いてもいい」と思うのは、/**/については正しいが、//については正しくない - uehaj's blogが詳しい。4、5回体験した結果、毎回オプションで指定することはやめ groovy.source.encoding を使うようにした。

groovyConsole

Java で動作しているのでコマンドプロンプトに限らない。Groovy AST Browser Improved! - uehaj's blogのように Ctrl+T で Groovy が変換していることのイメージがつかめると思う。Web 上にあるソースをただ実行するときはファイルを保存する必要すらなくなるので便利だ。コードを書くときも便利だが一晩たつと落ちることもあるのでその場合は保存しておくことをおすすめする。

#
# A fatal error has been detected by the Java Runtime Environment:
#

画面サイズなどを変更した場合は、右上の x ボタンではなく。File -> Exit で抜けると保存される。
間違っていたので訂正。Console.groovy を確認してみたところ変更時点で保存されている。

groovysh

たまに日本語が入力できないようなことをみかけるのだが正確には jline ではできないのであって groovysh 自体は普通に入力できる。入力には直接入力する方法(jline)と edit コマンドの2通りの方法がある。

edit コマンド

環境変数 EDITOR を設定しておくと edit コマンド*3でエディタが開く。Java で一時ファイルが作られるのだがファイルをロックできるエディタでないと入力前に削除されてコマンドが終了してしまうので注意する。
余談になるが最初のエントリで load コマンドは日本語を扱うのに文字コードを設定したのに何故 edit コマンドは必要ないかというと File#newReader は文字コードを推測してくれるためだ。load は URL で扱っているので推測してくれない。

jline

edit コマンドをおすすめするが直接日本語を入力するようにすることもできる。
groovysh の起動時に -T off オプションで jline を off にする方法だ。ただし結局 jline.UnsupportedTerminal が使われる。jline から得られた入力を変換する処理を Groovy に追記する必要がある。org.codehaus.groovy.tools.shell.InteractiveShellRunner.groovy を変更すれば一応動作する。

protected String readLine() {
    try {
        return new String(reader.readLine(prompt.call()).getBytes("ISO-8859-1"), java.nio.charset.Charset.defaultCharset().name())
    }
    catch (StringIndexOutOfBoundsException e) {
        log.debug("HACK: Try and work around GROOVY-2152 for now", e)

        return "";
    }
}

一応と言うのは jline.UnsupportedTerminal の改行コードは \r なので

groovy:000> groovy:000>

のように表示される。UnsupportedTerminal.java を変更すればいいのだがもう groovy の範疇ではないので面倒だ。jline の日本語 patch もみかけたことはあるが試したことはないので興味のある人は試してみるといいかもしれない。

groovysh の扱い

edit コマンドで入力していると groovyConsole と同じような感覚になるかもしれないが両者は扱いが異なる。groovysh は GroovyShell#evaluate が呼ばれている。つまり行単位だ。ただきりのいいところまで待ってくれる場合もある*4

groovy:000> def hello() {
groovy:001> println "hello"
groovy:002> }
===> true

あと Binding を共有しているのでこの場合 hello はメソッドクロージャとして保存されている。
そして変更したことはないが区切りの単位は変更できる。

org.codehaus.groovy.tools.shell.util.Preferences

groovysh も設定を保存できる。

groovy:000> import org.codehaus.groovy.tools.shell.util.*
===> [import org.codehaus.groovy.tools.shell.util.*]
groovy:000> Preferences.put("verbosity", "DEBUG")

と入力するとログレベルを DEBUG に変更できる。

groovy:000> Preferences.clear()

で初期状態に戻せる。
区切りも parser-flavor で変更できるし、環境変数 EDITOR を設定する変わりに editor に設定してもいい。groovysh の設定以外でもよく使うデータを保存しておいてもいいかもしれない。これらは java.util.Preferences を経由して Windows の場合はレジストリに保存される。

groovy コマンド

基本的に Java と同じなのだがトップレベルに処理を記述すると Script を継承したことになる。groovyConsole で確認すると理解できるかもしれない。スクリプト名は class 名になるので内部クラスやプロパティ名と衝突しないように注意する。この辺りは Groovy から Java に変換される際のことを意識する必要がある。


これでコマンドプロンプトでも Groovy のプログラミングを始められると思う。
Groovy をすすめるつもりはない*5が Groovy に興味を持った人の参考になればうれしい。
仕事で使用する言語ならともかく、趣味で使用するならなおさら些細な理由で気が変わるのだから。

これをモルトケからきいたメッケルは即答せず、あすまで考えさせてくれ、といった。その間、メッケルは日本人に会い、
「日本でモーゼル・ワインが手に入るか」
という一事だけをきいた。


坂の上の雲 (一) 』 司馬遼太郎

*1:Pure Java より速いぞ Groovy! - 倭マン's BLOG というようなこともできるらしい

*2:open++を使っている

*3:help で短縮形や他のコマンドを調べられる

*4:000 が行?番号

*5:誤解を招くかもしれないので書いておくが、Groovy はおすすめしないと言う意味ではなく、自分が使う言語は自分で判断してくださいと言う意味である