ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

Java・Scala Tuple・AsakusaFWの類似点・相違点

2015-12-13 08:44:55 | PG(分散処理)

Asakusa Framework Advent Calendar 2015の13日目です。

Scalaには「タプル」というものがあります。
複数の値を組にしてデータを保持するもの(クラス)で、メソッドから複数の値を返したい場合に便利です。
Object配列を使ったりするのとは違い、データの個数や型が規定できるのが良いです。

Javaには今のところタプルはありません。
OptionalStream APIラムダ式は導入されたけれども、「タプルが欲しい」という意見はたまに聞きます^^;

AsakusaFWでは、フローDSLで使うOperatorFactoryのメソッドの戻り値が、ちょうどタプルのような感じです。
ひとつのメソッド(処理結果)が複数のデータを出力することがあるので、それらを返すクラスとしてタプルのようなクラスが用いられます。
JJUGで発表した資料のBranchの例だと、resultという変数がタプル相当です)
ただし、AsakusaFWの場合はOperatorFactoryのメソッド毎に戻り値のクラスも生成する(メソッド名の先頭を大文字にしたクラス名になる)ので、タプルという共通クラスがあるわけではありませんが。

AsakusaFWでタプル相当の共通クラスがあってもよかったんじゃないか…とちょっと思ったんですが、タプルから値を取り出すときの名前(フィールド名)はOperatorメソッドの役割(演算子の種類)に応じて違う(ほとんどの場合はoutだが、updatedとかfoundとかmissedとか、メソッドによって異なる)ので、やはり個別に作る方が理に適っていそうです。


Java8 DateTime API・Scala・AsakusaFWの類似点・相違点

2015-12-12 14:35:31 | PG(分散処理)

Asakusa Framework Advent Calendar 2015の12日目です。

Java8では、日付を扱う新しいクラス群であるDate&Time APIが導入されました。日付・時刻といった「ある時点」を扱うクラスの他に、期間を表すPeriod・Durationといったクラスも追加になっています。

Scalaには、日付を扱う専用のクラスは無かったように思います。Javaのクラスをそのまま使う感じですかね。
ただ、期間を表すdurationというパッケージはあります。いまいち使い方を分かっていないんですけれども^^;

AsakusaFWには、日付を表すDateと、日付時刻を表すDateTimeが用意されています。
また、DateやDateTimeにも、DateOptionやDateTimeOptionというOption系クラスが存在しています。 
よく勘違いしてしまうんですが、AsakusaFWのDateは、java.util.Dateではなくcom.asakusafw.runtime.value.Dateです。1970年からではなく、西暦1年1月1日からの経過日数で値を保持しています。
DateTimeは秒まで保持します。ミリ秒以下は保持できません。
java.util.DateやCalendarとの変換は、経過日数(や秒数)を使って計算します。基本的なところはAsakusaFWのDateUtilで出来ますが。
AsakusaFWの対象JavaバージョンはJava7(JDK1.7)なので、今のところ、Java8のDate&Time APIとの変換方法はありません。(ただ、DateUtilの機能の少なさを見ると、Java8になっても変換方法はそんなに用意されないような気がします^^; てゆーか、Java8の日付関係クラスが多すぎるんですが(爆)) 


Shafu Gradleエラー

2015-12-11 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2015およびG*(Gradle)Advent Calendar 2015の11日目です。

Asakusa FrameworkにはEclipse上で開発する為のEclipseプラグイン『Shafu』というものがあります。
これを使うとほとんどの操作(Asakusaアプリケーション用新規プロジェクトの作成からコンパイルまで)をEclipse上で出来るので、とても便利です。


Shafuでのコンパイル関連機能は、内部でGradleタスクを実行することで実現されています。
(ちなみに、Shafuを入れると任意のGradleタスクをEclipse上から実行できるので、AsakusaFWと無関係に使っている人もいるとかいないとか?)
ただ、それに関してよくハマることがありますorz
Shafuの実行に使われるGradleのバージョンはbuild.gradleに書かれているものではなく(Shafu用の)Eclipseの設定で指定されたGradleバージョンが使われる、ということです。

ShafuのGradleバージョンは、デフォルトでは1.12であり、かなり古いです。たぶんShafuがリリースされた当時のバージョンがこれだったのでしょう。
今は、AsakusaFWの新規プロジェクトを作ると、2.8です。
まぁ、自分が使っているbuild.gradleのGradleラッパーのバージョンと合わせておけばいいでしょう。

少なくとも2系にしておかないと、コンパイルしたとき等に不可解な例外(何かのクラスが無いとか)が発生することが多いように思います。(こないだもShortTypeHandlingというクラスがエラーになって、なんだそりゃ?って感じでした)
サンプル通りにbuild.gradleを記述しているのに実行するとエラーが出る、という場合は、まずはGradleのバージョンを疑ってみるのが良さそうです。


JavaBeans・Scala case class・AsakusaFWの類似点・相違点

2015-12-10 00:00:00 | PG(分散処理)

Asakusa Framework Advent Calendar 2015の10日目です。

RDBのテーブルのデータをJavaで扱う場合、テーブルレイアウトと同等なプロパティー(フィールド)とセッター・ゲッターメソッドを持つJavaBeansのようなクラスを使うことがあるかと思います。

Scalaでは、そういう場合はcase classを使うのが便利です。
フィールドを定義するだけで、セッター・ゲッターメソッドおよびScalaで扱うのに便利なメソッドが自動生成されます。 

AsakusaFWでは、ファイルやRDBのテーブルから読み込んだ1レコード分のデータを扱うのに、データモデルと呼ぶクラスを使用します。
データモデルクラスは、DMDL(データモデル定義言語)というAsakusaFW独自の言語で記述し、コンパイルすることで生成されます。
表面上、データモデルクラスはゲッター・セッターメソッドを持つシンプルなクラスですが、内部ではそれぞれのプロパティーの値をOption系クラスアドベントカレンダー8日目参照)で保持しており、Option系クラスでアクセスするメソッドも提供されています。
また、HadoopのWritable関連のメソッド(シリアライズ・デシリアライズに使う)も実装されています。

Java8のOptionalは基本的にメソッドの戻り値で使うことが推奨されており、普通はフィールドで保持するのには使いません。
が、AsakusaFWで扱う対象であるRDBのテーブルにはnullが入っていることがありますし、CSVファイルで何も入っていない項目はnullとして扱います。また、AsakusaFWのOption系クラスはWritableの機能も持っているので、データモデルクラスのフィールドはOption系クラスで保持するようになっているのだと思います。(データモデルのWritable関連メソッドは、フィールドのOption系クラスのWritable用メソッドを順番に呼ぶような実装になっています)

ちなみに、AsakusaFWのStringOptionは、内部ではHadoopのTextクラスで保持するようになっています。
HadoopのWritableを扱う上ではその方がいいかもしれないですが、今後Hadoop以外を相手にすることになったら、足を引っ張りそうな気がしてちょっと心配です(苦笑)