メンバネームスペース

導入することにしました。

導入理由

Xtalは、既存のクラスにメソッドなどを追加することが出来ます。

Iterator::x2: method fiber{
  this{
    yield it*2;
  }
}

// 次のように使える
10.times.x2{
  it.p;
}

このように、Iteratorクラスに「要素を2倍にしてそれをブロックパラメータとするイテレータを返すメソッド」を追加したくなったとします。これにはある抵抗があります。

「もし他のライブラリが同じ名前で既に追加してたらどうしよう?」

そう思うと、迂闊に追加することができません。

回避方法として、mylibname_x2 とか被らないであろうプレフィックスをつけるという手段があります。これはあまりに綺麗でなく、さらにそれでも衝突の恐れが0とはいえません。メンバネームスペースはこれを解決します。

ns: class{}

Iterator::x2#ns: method fiber{
  this{
    yield it*2;
  }
}

// 次のように使える
10.times.x2#ns{
  it.p;
}

簡単に言うと、Xtalにおいてメンバネームスペースとは、「メンバの定義、検索を、識別子となんらかのオブジェクトの二つのキーで出来る機能」です。

検索時、二つ目のキーは、=== (同一かを調べる演算子)で等しいか比較され、それが偽の場合はis_inheritedを使って行われます。

A: class{}
B: class(A){} // Aを継承する

Iterator::x2#A: method{ "boo".p; } // 識別子 x2 と、 Aオブジェクトを使って定義する

10.times.x2#A; // A===Aなので検索される
10.times.x2#B; // A===Bはtrueではないが、 B.is_inherited(A)はtrueなので検索される。


どちらのキーも、=== (同一かを調べる演算子)で検索することにしました。is_inheritedを使う方法は便利な側面があったのですが、複数のメンバが発見されたときどうするか、など無駄に複雑性が増すため止めます。

なお、メンバネームスペースを省略出来る構文は持ちません。これは迂闊に省略するとバグが発生しやすいと予想したためです。