Guillaume Laforge氏のブログより、Groovy 1.5.7と1.6-beta-2についての記事を翻訳してみました。
ーーーーー翻訳ここからーーーーー
今回、Groovy開発チームとG2Oneが、Groovy 1.5.7とGroovy 1.6-beta-2の同時リリースをアナウンスできることを嬉しく思います。Groovy 1.5.7は現時点での安定板の保守リリースであり、Groovy 1.6-beta-2は来るべきメジャーリリースです。
Groovy 1.5.7は主にはバグ修正(61件)ですが、1.6ブランチからバックポートされた些少ないくつかのAPI改善(20件)も含んでいます。一方、Groovy 1.6-beta-2は多くの目新しいものを含んでいます(68件のバグ修正と38の改善と新機能)。以下、beta-2の新機能について説明したいと思います。
beta-1で行った、コンパイル時および実行時の性能向上を引き続き行いながら、beta-2ではそれをさらに推し進めました。しかし、皆さんは、本リリースにおける新機能や変更のほうにも興味があるとおもいます。
●マルチ代入(複数の変数に対する代入)
beta-1では、「マルチ代入機能(multiple assignment)」が導入されました。しかしながら、添え字記法に、いくつかの問題とあいまいさが発生したので、角括弧の代わりに丸括弧を使用するように文法をちょっとだけ変えました。われわれは、代入に関するすべてのユースケースをカバーするようにしました(以前のバージョンではすべてのケースをカバーしていなかった)。
現バージョンでは、以下のようにいくつかの変数を定義しかつ同時に代入することができます。
def (a, b) = [1,2] assert a == 1 assert b == 2
以下のように変数の型を定義することもできます。
def (int i, String j) = [1, 'Groovy']
変数定義なしで代入を行うには、単に'def'キーワードを取り除きます。
def a, b (a, b) = functionReturningAList()
そのほかには、上記の構文の変更を除けば、beta-1と振る舞いは替わっていません。もし、右辺のリストの要素数が左辺の変数の個数よりも多いなら、先頭の要素から、その順に代入が行われます。また、要素数が変数の個数よりも少ないなら、あまった変数にはnullが代入されます。
●if/elseおよびtry/catch/finallyブロックにおけるreturnの省略
文法に変化はありませんが、振る舞いに関する変更があります。if/elseおよびtry/catch/finallyブロックは、それがコードの最後の文であるなら、明示的なreturnを使用せずに値を返すことができます。
たとえば、以下のメソッドでは、returnを省略していますが、1を返します。
def method() { if (true) 1 else 0 }
この振る舞いの概要を知りたい場合、テストケースを参照してください。
●AST変換
ごく稀にではありますが、新機能を実現するために、Groovyの文法を拡張することが良い考えだと思えることがあります(たとえば、さっきのマルチ代入の場合とか)。でも、多くの場合、新しいコンセプトを表現するために、Groovyの構文に簡単にキーワードを追加したり、新しい文法構造を導入したりすることはできません。しかし今回、beta-1で開始され導入されたAST(Abstract Syntax Tree)変換というアイデアによって、文法を変更せずとも、新しく革新的なアイデアに取り組むことができるようになったのです。
Ast変換では、コンパイル過程にフックをかけて、 コンパイル中のプログラムを変更することができます。AST変換はGroovyに「コンパイル時メタプログラミング」の能力を与えます。これは、実行時の性能を劣化させずに、言語レベルに強力な柔軟性を与えてくれるものです。
beta-1では、2つのAST変換が導入されました。これらは、われわれの才能豊かなGroovy Swingチームkによって開拓されたものです。「@Bindable」変換マーカーアノテーションによって、アノテーションが付加されたプロパティのためのプロパティリスナーが透過的にクラスに追加されます。
beta-2では、以下の新しい変換が追加されています。
- @Singletonは、クラスをシングルトンに変換します(例)
- @Immutableは、インスタンスが生成された後での変更を禁止します(例)
- @Delegateは、委譲(delegation)パターンを透過的に実現します(例)
- @Lazyは、プロパティの怠惰(Lazily)な初期化を指定します(例)
- @Category / @Mixin は、カテゴリのメソッドをコンパイル時にmixinするのに役立ちます(例)
- @Newifyは、インスタンス生成の際に'new'キーワードを省略することができます。単に「Integer(5)」と書けばインスタンスが生成されます。Integer.new(5)みたいなRubyっぽい文法を使う能力を与えてくれます。
これらの変換に関するドキュメントは、最終リリースに間に合うように提供されるでしょう。それまでの間は、更なる情報を知りたい場合には、メーリングリストにどしどし質問してくださいますよう。
●Swingビルダー
AST変換の先駆者であるSwingビルダーには、単純クロージャのバインディングのサポートが追加されました。たとえば、bean(property: bind {otherBean.property } )は、bind(source: otherBean, target: property) と同じです。bean(location: bind {pos.x + ',' + pos.y} )のような複雑な式でも同様にクロージャで大丈夫です。
●Grape・・適応的・先進的パッケージング・エンジン
AST変換による強化として、Groovy 1.6-beta-2では「Groovy Advanced or Adaptable Packaging Engine(Groovy先進もしくは適応的パッケージング・エンジン)」のプレビューバージョンを提供します。Groovyスクリプトは、明示的に@Grab変換アノテーションあるいはGrape.grab()メソッドを呼ぶことで、特定のライブラリを要求することができます。ランタイムが必要なJARを見つけてくれます。Grapeでは、あなたは依存性のあるライブラリ無しでスクリプトを容易に配布することができ、それらのライブラリはそのスクリプトを最初に実行したときにダウンロードされます。
Grapeに関する情報については、ドキュメンテーションを参考にしてください。
●インスタンスごとのメタクラスをPOJOにも
今までは、、Groovyクラスはインスタンスごとにメタクラスを持つことができましたが、Javaクラス(POJO)はすべてのインスタンスに対してひとつのメタクラスしか持つことができませんでした(つまりクラスごとのメタクラス)。今や、この制限は解除され、POJOもインスタンスごとのメタクラスを持つことができるようになりました。ちなみにメタクラスプロパティにnullを設定するとデフォルトのメタクラスに戻ります。
●ExpandoMetaClass DSL
通常のobject.metaClass表現を使用せずに、EMCを通じて、あらたなメソッドをチェイニングできるようにするためのEMCのための新たなDSLが作られました。
テストコード中にいくつかの例をこちらで見ることができます(こことかこちら)。
●実行時mixin
今日ご紹介する最後の機能は、実行時mixinです。@Category/@Mixinとは違って、あるいは@Delegate変換とも違って、その名称が暗示するように、振る舞いを実行時にmixinします。EMC DSLを組み合わせて使用した例をここで見ることができます。
●有用なリンク
以下から両方のバージョンをダウンロードできます。セントラルMavenリポジトリからJARが利用可能になる予定です。
1.5.7および1.6-beta-2のリリースノートはJIRAから読むことができます。
●今後の展望
Groovyのロードマップは多少変更されました。1.7で実現される予定であった機能は、1.6ですでに実装されており、1.7の範囲は短縮され、1.8は不要となりました。
したがって、1.6の後では、ある主要な新機能(Javaとの小さな差異を解消するため、Groovyで無名内部クラスを定義する)を実現することが中心となる、1.7に集中することになります。そのあとで、われわれは、将来のバージョンにおける、より強力な機能を実現するための基盤として、またより優れた実行性能を実現するような、Groovy中核部分を改善し書き直したGroovy 2.0に努力を集中することができるようになるでしょう。
これら2つのリリースについて、フィードバックを期待しています。
支援いただき、また、貢献していただいたすべての皆様に感謝します。
Enjoy!
Guillaume Laforge
Groovy Project Manager
G2One, Inc. Vice-President Technology
http://www.g2one.com