Ruby1.9 のクラスのメタ階層を整理する 4


ぜんぜん関係ない話ですが、この記事で Yugui さんが、ごくふつうのことのように Smalltalk を使って確かめた結果を例として挙げてくださっているのが個人的にはとっても嬉しかったです。

とかく世間では敬遠されがちですが、じつのところ Smalltalk はとってもシンプルな代物なので(文法は「object message」のみで、処理系は「do it」と「print it」相当の操作を組み合わせるだけでたいていのことは可能)、他の多くの人にもこんなふうに気軽に動かして中身を探索し、面白いネタを掘り起こしてもらえればなと願っています。


さて。いくつか気になった点を以下に書き出してみました。

クラス、メタクラス、メタメタクラスと辿る上でSmalltalkのMetaclass classに近いのは、たぶんだけれども、#ではなくてClassのほう。

ここのところ、ちょっとわかりにくかったです。図3でも、Ruby の Class はメタメタな存在には見えません。おそらくは前後の文脈から察するに、

クラス、メタクラス、メタメタクラスと辿る上でSmalltalkMetaclassに近いのは、たぶんだけれども、Classではなくて#のほう。

ということをおっしゃりたかったのでしょうか。これなら図3については、またくその通りです。


ともあれ、図3のように変更されたことで、Ruby のクラスのメタ階層での振る舞いや手を加えたときの影響の及び方が以前よりは予測しやすいものになったと思います。

なにより、(Ruby の複雑な動きに対する)理解を「整理する」つもりが、この短期間で、実際の有り様のほうが「整理」されてしまったことに少なからず驚いています。さすがです。


Ruby式にクラスに属する何かをオブジェクトと呼びましょう。そうすると、Smalltalkにおけるクラスはオブジェクトではありません。なぜならば、クラスはメタクラスに属するのであって、メタクラスはクラス(isKindOf: Class)ではないからです。クラスはクラスには属しません。

これはたしかに「isKindOf: Class」に限定すればその通りなのですが、一方で、Smalltalk では Class と Metaclass はともに共通の ClassDescription や Behavior という抽象クラスを継承しており、これらこそがクラスの本質の記述である…という実情があります。したがって、Ruby のクラス同様に Smalltalk のクラスも(クラスのインスタンスというくくりでの)「オブジェクト」だと言ってかまわないと思います。

Class superclass       "=> ClassDescription "
Metaclass superclass   "=> ClassDescription "
Object isKindOf: ClassDescription         "=> true "
Object class isKindOf: ClassDescription   "=> true "


思うに、RubySmalltalk は非常によく似ているので、(Ruby のモジュールや Squeak Smalltalk のトレイトといった、それぞれに独自の機能を無視してよい文脈では)考え方をあえて違えて説明を付けようとする必要ないように感じました。

この場合、違いが生じる理由を探すとすれば「大クラス主義」か否かというあたりだと思います。Smalltalk で Class(|Metaclass) < ClassDescription < Behavior に分けているものを、Ruby ではがっつり Class にまとめてしまっただけの話…みたいな。


同様に、図3が Ruby にとって“正解”であることも、この大クラス主義であることで説明可能だと思います。Ruby の # は、Smalltalk の Class class と Metaclass、 Metaclass class に与えられた役割をひとつのクラスにまとめてしまったものだと見なすことができるからです。

実際、id:sumim:20080913:p2 に示した Squeak Smalltalk のクラスのメタ構造の図をそのようにしてまとめると Ruby の図3そっくりなのができあがります。


ただこのようにざっくりとひとつのクラス(とそれと組のメタクラス)にまとめてしまうことで、Ruby では特異クラスだけ狙って共通の機能を持たせられないとか、Class というオブジェクトが独自の振る舞いを持つことができなくなる…という Smalltalk にはない制約が生じてしまっています。とは言え、ひるがえって Smalltalk において、Class、ClassDescription、Behavior に、たいしたクラスメソッドを持たせていない現状を鑑みるに、ほとんど実害はないとも思われますが。