Masatake YAMATO
jet****@gyve*****
2004年 1月 9日 (金) 17:24:23 JST
> > 早速質問があります。 > > http://www.shiro.dreamhost.com/scheme/gauche/oldnews-j.html > > によるとクラスメソッドを定義できるようになったとあるのですが、 > > どのようにすれば定義できるのでしょうか? > > これは、多くの組み込みクラスがデフォルトでユニークなメタクラスを > 持っていることを指しています。つまり、<list>クラスに特有のメソッドを > 定義するには、そのメタクラスである<list-meta>に対してメソッドを > 定義すれば良い、ということです。 > > (define-method foo ((class <list-meta>)) > ...) > > 例えば、gauche.collectionのいくつかのメソッドはこれを利用して、 > 結果の値の型をクラスで指定できるようになっています。 > > (map-to <list> + '(1 2 3) '#(4 5 6)) => (5 7 9) > (map-to <vector> + '(1 2 3) '#(4 5 6)) => #(5 7 9) > (map-to <u8vector> + '(1 2 3) '#(4 5 6)) => #u8(5 7 9) > > ただ、ユーザ定義クラスで同様のことをやるには、自分でメタクラスを > 作ってやる必要があります。 ありがとうございます。うまくクラスメソッドを定義することができ ました。しかしメタクラスを定義するのが手間ですね。 > なお、同様の操作は、CLOSではeql specializerというもので > 実現できます。これは引数の型ではなく特定の引数そのもので > ディスパッチするというものです。Rubyの特異メソッドみたいなものです。 > > もともと、クラスに対するメソッドをつけたかったのですが、 > eql specializer同等の機構を現在のVMで実装する方法がうまく > 思い付かなかったので、この方法(組み込みクラスのメタクラス)を > 採用しました。ただ、メタクラスが増えまくってしまうとか、 > あまり気に入っていない点もあります。 > > 最近、eql specializer相当のものを効率良く実装できるかも、という > 方法を思い付いたので、長期的には「組み込みクラスのメタクラス」から > そちらに移行するかもしれません。 なるほど。クラス変数なんかはどこに格納されて いるのでしょうか。これも独自のメタクラスが必要かな と思ったのですが、 gosh> (define-class <a> () ((a :allocation :class :init-value 1))) <a> gosh> (define-class <b> () ((a :allocation :class :init-value 1))) <b> gosh> (slot-set! (make <a>) 'a 2) 2 gosh> (slot-ref (make <a>) 'a) 2 gosh> (slot-ref (make <b>) 'a) 1 gosh> みたいに<a>, <b>ごとに値を保持できています。