インスタンスベース・オブジェクト指向

多くのプログラミング言語におけるオブジェクト指向は、オブジェクトの生成に際し、 クラスを定義し、そのインスタンスを生成するという形をとります。 これを、クラスベース・オブジェクト指向と呼びます。 これに対し、Cyan におけるオブジェクト指向では、 クラスという概念を用いずともオブジェクトを生成できます。 これが、Cyan のインスタンスベース・オブジェクト指向です。

Cyan におけるオブジェクトは、 スロットメッセージペアレントへの委譲という三つの概念を持ちます。 スロットとは、クラスベースにおけるフィールドとメソッドの両方を担います。 アクセスに制限はありません。次のようにしてアクセスします。

 
# オブジェクト human のスロット name へのアクセス
human.name

また、スロットには関数をセットすることができ、これをメソッドとして呼び出せます。 メソッドを呼び出すには、メッセージを引数と共に送ります。

 
# human に対して walk というメッセージを "east" という引数と共に送る。
human.walk("east")

メッセージを受け取ったオブジェクトは、 自身にメッセージと同名のスロットがある場合、 そこにセットされた関数を呼び出します。 その際、メッセージと共に受け取った引数に、第一引数として自身を追加し、 それを引数とします。

しかし、自身にメッセージと同名のスロットが見つからない場合、 parent というスロットにセットされたオブジェクトにそのメッセージを送ります。 このオブジェクトをペアレントと呼び、この動作をペアレントへの委譲と呼びます。 逆に、あるオブジェクトに対し、それをペアレントとするオブジェクトのことを チャイルドと呼びます。

ちなみに、スロットへのアクセスにおいても、自身にスロットが見つからない場合 ペアレントのスロットを探します。

ペアレントは、クラスベースにおけるクラスとして使用することができます。 また、ペアレントのペアレントを設定すれば、クラスの継承を実現できます。 つまり、ペアレントとチャイルドの関係は、 クラスとインスタンス、スーパークラスとサブクラスの関係を内包します。

これらを踏まえて、実際にコードを書いてみましょう。 ちなみに、Cyan のオブジェクトはペアレントをたどっていくと、 必ず Object というオブジェクトに行き着きます。 Object には基本的なメソッドが定義されており、 その1つが自身のチャイルドを作成する child メソッドです。

 
Human = Object.child()
Human.walk = ^(self, dir){
  say(self.name + " walked " + dir + ".")
}

Superman = Human.child()
Superman.fly = ^(self, dir){
  say(self.name + " flew " + dir + ".")
}

human = Human.child()
human.name = "John"
human.walk("east")  #=> John walked east.

superman = Superman.child()
superman.name = "Clark"
superman.fly("north")  #=> Clark flew north.
superman.walk("west")  #=> Clark walked west.

Human である John は歩くことしかできませんが、 Superman である Clark は飛ぶことができます。 もちろん、Clark は歩くこともできます。

上記のコードにおいて、^(self, dir){ .. } という記述がありますが、 これは無名関数です。ここでは簡単にするため、 インデントブロックmethod 関数self の省略などを使っていませんが、 これらを使えばもっとスマートに記述することができます。 また、say(..) というのは、標準出力に引数として渡されたオブジェクトを表示する 関数 say の呼び出しです。

インスタンスベースの利点は、オブジェクトに対して、 動的にメソッドの追加・変更ができることです。 その際、オブジェクトがクラスであっても構いません。 また、スロット parent の内容を変更すれば、ペアレントも動的に変えられます。 これにより、コードの可能性が広がります。

さらに、先ほど式とオブジェクトの項で述べたように、 Cyan の抽象構文木はファーストクラスのオブジェクトですから、 スロットの編集によってコードを編集できるわけです。

ちなみに、Cyanで言うインスタンスベース・オブジェクト指向は、 プロトタイプベース・オブジェクト指向言語(特に Io)における プロトタイプをペアレント、クローンをチャイルドと言い換えたものとして用いています。