メタクラス入門(暫定版)

#05/08/2001 最終変更
#05/04/2000 新規作成

new の謎

FileList を使いたくて、デバッガで使い方を調べてみました。
こんなクラスメソッドを書いて、Workspace で TestFile go



デバッガから、step, send で StringHolder の new にはいりました。



しかしこの後、 send を押せど、反応ゼロ。System Browser を見ても、上位クラスに new は定義されていません。
??? というわけで、本をみたら 「Behaviorに定義されてるよ」とのこと。早速見てみると、確かにあります。
あっ、 これがウワサのメタクラスか! というわけで、調査開始。



以下、「Smalltalk by Example」 (Alec Sharp著) 29章、Meta-Programming の抜書きと実験。
内容は、Squeakに置き換えてあります。

・an OrderedCollection が class OrderedCollection のインスタンスであると同じく、
  class OrderedCollection も他のクラスのインスタンスである。この、インスタンスがクラスである
  クラスをメタクラスという。従って、class OrderedCollection はそのメタクラスのインスタンスで
  ある。

・新しいクラスを定義すると、新しいメタクラスが自動的につくられる。そのメタクラスは一つだけイン
  スタンスを持っている。定義された新しいクラスだ。

・メタクラスは class MetaClass のインスタンスであり、名前は無い。したがって、Browserでみること
  は出来ない。

・Squeakで、以下のコマンドを打ってみる
   Object allSubclasses size. ->3176
   Smalltalk classNames size. ->1592
   Object は、Smalltalk のクラス名の約2倍の数をもっている。これが、各クラスが独自のメタクラスを
   持っていることを示す。

・クラスはメタクラスのインスタンスなのだから、我々がクラスメソッドと考えるのは、実際は、クラスの
  メタクラスのインスタンスメソッドである。

・クラスのメタクラスの methodDic 変数に、クラスのインスタンスが呼び出す(クラス)メソッドを登録
  している。

・実験。実際にメタクラスを見てみる。(BankAccountチュートリアルの例:どのクラスでもいい)
  Workspace で BankAccount inspect. と入力して alt -d 
  Workspace で BankAccount class inspect. と入力して alt -d
 
BankAccount クラス

メソッドデクショナリには、インスタンス
メソッドが並んでいる。
・balance, balance:, deposit:, historyMorph, initialize, wihtdraw
           
BankAccount クラス のメタクラス

メソッドデクショナリには、BanAccount の
クラスメソッドが見える。

・execute, new


superclass は Object class である


クラス変数 Ownerを追加した。これは、BankAccount のプール辞書に見える




クラスインスタンス変数を追加した。

メタクラスのインスタンス変数に表示される
・BankAccount のインスタンス、クラスメソッドの数を知りたければ、以下のようにする。 BankAccount selectors size. ->6 BankAccount class selectors size. ->2 BankAccount selectors size + BankAccount class selectors size. ->8 ・MyClass>>MyInstanceMethod と MyClass class>>MyClassMethod という書式は、class がメタクラスを返すことを構造を 記述している。 ・インスタンスメソッドは、そのクラスかスーバークラスで定義される。同様に、 クラスメソッドは、そのメタクラスかメタクラスのスーバークラスで定義される。 alt - p してみよう。 継承関係の確認 Metaclass superclass. ->ClassDescription Class superclass. ->ClassDescription ClassDescription superclass. ->Behavior Behavior superclass. ->Object Object superclass. ->ProtoObject ProtoObject superclass. ->nil インスタンス関係の確認 Object class. ->Object class Object class class. ->Metaclass Metaclass class. ->Metaclass class (ここで終わり。上位のメタクラスは無い)
● 「Smalltalk, Objects, and Design」 (Chamond Liu著) 20章 Metaclass P260 より ● 「Smalltalk イディオム」 (青木 淳)より p.66 もう少し敷延して大胆に述べれば、クラスでさえ、何かのクラスのインスタンスであり、Smalltalkの オブジェクトメモリには、インスタンスだけが存在し、クラスが存在しません。クラスとインスタンスの 関係は、広大なオブジェクトメモリに展開しているオブジェクト達の間に、便宜的に敷かれた関係であり その関係自身を捨象すれば、クラスとインスタンスの区別がなくなり、全てがオブジェクトという Smalltalkの風光が見えてきます。
(暫定版終了 05/08)