CLOS のパッケージを用いたメソッドコンフリクトへの対処を試みる

昨日のエントリーで shiro さんにコメントをいただいたのをうけて、さっそく CLOS のパッケージについて学んでみました。


これらから得られた知識を元に、前のエントリーでの例で、メソッド(総称関数)名のコンフリクトを回避するとしたらこんなふうにするのかな…と想像したのを書いてみます。

;; b1.cl
(defpackage b1 (:export :<b1> :f1 :f2))
(in-package b1)
(defclass <b1> () ())
(defmethod f1 ((_ <b1>)) "B1::F1")
(defmethod f2 ((_ <b1>)) "B1::F2")
;; b2.cl
(defpackage b2 (:export :<b2> :f1 :f2))
(in-package b2)
(defclass <b2> () ())
(defmethod f1 ((_ <b2>)) "B2::F1")
(defmethod f2 ((_ <b2>)) "B2::F2")

基底クラス の定義は、無意味にファイルにしてみました(^_^;)。

(require "b1")
(require "b2")

(unexport '(b1::f2) 'b1)
(unexport '(b2::f1) 'b2)
(use-package '(b1 b2))

(defclass <c> (<b1> <b2>) ())
(setq c (make-instance '<c>))
(f1 c)        ;;=> "B1::F1"
(f2 c)        ;;=> "B2::F2"

これは f1 は の、f2 は のを使いたい場合。


次のようにすると、f1 は の、f2 は のと逆にできます。

(unexport '(b1::f1) 'b1)
(export '(b2::f1) 'b2)
(unexport '(b2::f2) 'b2)
(export '(b1::f2) 'b1)
(f1 c)        ;;=> "B2::F1"
(f2 c)        ;;=> "B1::F2"


不慣れ故、ひどく回りくどいことをやっているような気もしなくもないですが(^_^;)、とりあえず、CLOS でもメソッド単位での取捨選択が可能だということが自分でも試せたということで…。