達人スターターキット・写経7日目

今更ながら、やっていることは写経ではなくて本の中の演習問題を解いているだけだと気づきました。ま、とりあえず題名はもうこのままで…


今日のお題は、インターフェースとユニットテストが与えられた状態でモックオブジェクトを作れというもの。今までは、インターフェースが与えられた状態で、そのI/Fに合うようなオブジェクトを作成してテストをしなさいというものだったので、テストを考える分の手間が省けました。いや、この写経の主旨はユニットテスト作成の際の勘所を養うというものなので、できればテストの方を作成したいのですが…。

ともあれ、着々とテスト作成⇔モックオブジェクト作成⇔テスト実行を繰り返す。あとは、ちょこちょこっと適当なタイミングでリファクタリング。もちろん、テストも忘れずに。


と、ここで「メソッドの抽出」を行っているときにふとJavaABAPの違いについて頭に浮かんだことをつらつらと。他の言語と比べてABAPがイケテない点は、メソッドの戻り値をそのまま他の式に埋め込むことができないということ*1

例えば、Javaだとこんな感じにできます*2

private int index;
private ArrayList<String> list;

private int getIndex() {
  return index;
}

public String getStr() {
  return list.get(getIndex());
}

これが、ABAPだとこう書かないといけない。

DATA: INDEX TYPE I.
DATA: LIST  TYPE TABLE OF STRING.

FORM GETINDEX CHANGING O_INDEX.
  O_INDEX = INDEX.
ENDFORM.

FORM GETSTR CHANGING O_STR.
  DATA: L_INDEX TYPE I.
  
  PERFORM GETINDEX CHANGING L_INDEX.
  READ TABLE LIST INTO O_STR INDEX L_INDEX.
ENDFORM.

つまり、メソッド(ここではサブルーチン)の戻り値を受けるために一時変数(L_INDEX)を用意しないといけないということです。Javaなどでは極力メソッドを(数を増やして)中身を短くしなさいとありますが、下手にABAPでそれをやると一時変数が多くなって逆に見づらくなるのです。

なんでこんな言語仕様になっているかですが、ABAPでは複数戻り値を許容しているからと考えます。戻り値が複数あると、他の式の中に組み込んだときにどの戻り値を採用すればいいのかが判断できないので、一旦一時変数で受けなければならないのでしょう。

けど、複数の戻り値を扱いたいのであればオブジェクトとしてまとめるなり構造として定義するなりで他に色々やりようはあるので、今となってはこの仕様は負の影響が強いような気がします。少なくとも、私は最初ABAPに触ったときにものすごい違和感がありました。


何か話が若干逸れたけど、やっぱりこういうのも頭の中だけでなく実際にやってみて分かることですよね。手を動かすこと大事!

*1:ABAP Objectでは、Returningパラメータを用いれば実現可能

*2:コードは明らかに簡略化していますので、実用的なものかは置いておきます。