v0.23 Release Note

Last updated:
Created: 2007-09-11








by Fumisky Wells
v0.19 以来の久々の仕様変更 + 追加です:
  1. raise 文の追加
  2. rescue 句の構文の変更
  3. 階層化 enum の追加
  4. 階層化 enum の1つである err 型の追加

raise 文の追加

ようやくプログラム内で raise できるようになりました。 raise で渡せるのは err 型変数だけです。補助的に文字列も渡せます。 err型は enum の1つに過ぎません。つまり、32bit 整数と同レベルの 表現しか出来ません。しかし、Alan の enum は "階層化 enum" と名付けているように、bit mask でグルーピングできるようにしています。

raise で投げられる型が 32bit enum 限定なのは下記の理由からです:

  1. 例外時に複雑なオブジェクトを投げるようにするのは、事態を複雑に し過ぎである、と考えています。実装をシンプルにする方を選びました。
    (もっとも、C++, Java, Ruby など、実用的な言語は 例外を扱うベースクラスから派生する形で任意のオブジェクトを 投げることができるようになっています。これは、つまり現場からの 要請としてそのように汎用的になったのだと思われます。そうすると 今の Alan の仕様では実際の問題を解決できない場合があるということ かも知れません。)
  2. Alan ではエラー = 例外であり、エラーを表すのに 32bit enum が必要十分 だろうからと考えたから。
  3. 初期の Ruby も例外で渡せるのはエラー番号 + 文字列程度だったと 記憶しています。 その後の発展で任意の(Exceptionから派生した)オブジェクト を渡せるようになった経緯は Alan の今後を占う意味で参考になると 思っています。 汎用的なオブジェクトを渡す実装は今の私には時間がかかりすぎます。 とりあえず 32bit enum を渡すことで一旦終わりとし、次の実装 (v0.24 pipeline)に移りたいからという現実的な制約も、32bit enum 止まりとした大きな理由です(苦笑)。

rescue 句の構文の変更

err型導入にともない、どの値を rescue するかを選択できるように、 rescue 句を下記のように変更します:
  void: f()
      :
  rescue err.FPE then           # 0 で割ったエラー
      :
  rescue err.str.CONV_INT,
         err.str.CONV_REAL then # 文字列の整数・実数変換エラー
      :
  rescue err.rex then           # 正規表現系のエラー全て
      :
  rescue then                   # その他 rescue できなかったもの全て
      :
  end

階層化 enum の追加

Alan にも enum 型を導入しました。型定義は
enum Name A, B, ... end
  
とします。enum のグループ化が可能で、
enum Family
  father, mother
  enum children
    elest, elder, me, younger, youngest
  end
end
  
と定義でき、この場合、グループに属しているかどうかを in 演算子で チェックできます:
Family: f = Family.children.elder

if f == Family.children.me then
  put("Me!\n")
elsif f in Family.children then
  put("Brother/Sister!\n")
else
  put("Daddy/Mom!\n")
end
  
比較 ==, <> は 32bit 整数と同等、in 演算は 32bit bitmask と同等 です。

上の例を見てお分かりのように、名前空間が C/C++ などの enum とは 異なり、enum 型の型名が必ず要素の前につきます。つまり、上の例で言うと me は必ず Family.children.me と指定しなければなりません。 C/C++ の enum は、C/C++ のブロック {...} の中で唯一名前空間が括弧 {...} に限定されないものですが、この規則のため、私はいつも使い方を 間違えていました(^^;)。要素名の有効な名前空間が広すぎるなぁと いつも思っていたので、Alan では限定することにしました。

階層化 enum の1つである err 型の追加

上の階層化 enum はそれ自体一つのユーザ定義型として使用できるのですが、 Alan では enum の1つとして err型を組み込み型として使用しており、 例外発生/処理時の raise() や rescue で使用します。

Ruby のオープンクラスよろしくオープンenum としてユーザが自由に err型に エラーコードを追加していき... としたいですが、今はできませんm(__)m。

現在どのようなエラーコードが定義されているかは

  put(err)
  
で分かります。

err型導入が実は主で、階層化enumはその目的のために導入したのだった。