2012-02-20 18 views
8

私は様々な要素に対してHTMLを発行するいくつかのメソッドを書いています。各メソッドは同じ出力を持ちますが、必ずしも同じ入力が必要なわけではありません。defgenericの任意の引数?

(各プレイヤーは唯一、自分の作品を見ているので)その発送は実際にある(プレーヤーごとに変更する必要はありません、ボード・スペースをエコー

(defmethod echo ((board game-board) (p player)) ...) 

同様playerを取るためにgame-boardニーズをエコーする方法game-boardメソッドで行われます。後でスペースのechoが呼び出されます)。理想的には、私は

(defmethod echo ((space board-space)) ...) 
(defmethod echo ((space empty-space)) ...) 

それは私が後できちんと自分自身を表示するためには、単にプレイヤーよりも多くを知っている必要がありますオブジェクトに実行することも考えだ行うことができると思います。エラー

The generic function #<STANDARD-GENERIC-FUNCTION ECHO (4)> takes 2 required arguments; 

を与えるだろうけれども、同じジェネリックに特化した方法は、すでに存在しているので、それは戻って、これらの方法echo-spaceecho-boardなどに名前を付けることが理想的とは言えそうです。

特殊なオブジェクトに基づいて他の引数を変更する正規の方法はありますか?私は

(defgeneric echo (thing &key player ...) ...) 

または

(defgeneric echo (thing &rest other-args) ...) 

のような何かをするべきか?より一般的に言えば、具体的にdefgenericに関するまともなチュートリアルを教えてもらえますか? (関連するPCLの章とsome CLOS tutorialsを読んだことがありますが、私がここで質問している状況は含まれていません)。

答えて

5

一般に、2つの機能のインターフェイスが多すぎると、実際には同じ操作の特殊化ではなく、同じ名前であってはならないことを示します。オプションの/ key引数を特殊化したいのであれば、それを達成する方法は汎用関数を呼び出す通常の関数を使用し、それを特化する欠落引数のデフォルト値を与えることです。

Keene's bookは、CLOSの最も包括的なガイドだと思います。残念ながら、それは本の形でしか利用できないようです。

+0

ジェネリックにファンクションディスパッチすることは、(エコーボード/エコースペース/等の領域に)戻ってしまうのではないかと思われます。私はあなたがこの場合に正しいと思います。エコー(単なるアイテムを出力する)と、別のエコーテイラー(echo-tailored)または同様のもの(追加のパラメータに基づいて出力を変更する)のようなものを定義する方が良いかもしれません。 – Inaimathi

+0

非ジェネリック関数はディスパッチを行わず、単に引数を正規化します。これは明らかにジェネリック(とメソッド)がすべての引数をとることを必要とします。なぜなら、これはインターフェイスが実際に似ている場合にのみ有用な理由です。 – Ramarren

+0

ここにはKeeneの本のPDFがあります(私はこの法律の有効性について知らないので、助言してください):https://doc.lagout.org/programmation/Lisp/Object-Oriented%20Programming%20in%20Common%20Lisp_% 20A%20プログラマー%27s%20ガイド%20to%20CLOS%20%5BKeene%201989-01-11%5D.pdf –

0

オブジェクト/クラスを再構成して、エコーしたい各オブジェクトがそれ自身の(継承された)スロットに必要なすべてのプロパティを持つようにするにはどうすればよいですか?

あなたが必要とするものが既にオブジェクトに格納されているので、オブジェクトにechoを呼び出すときに、それらを引数として渡す必要はありません。

3

メソッドが同じパラメータを使用し、データ型だけが異なる場合は、より簡単です。しかし、ジェネリック関数とメソッドがすべて同じ名前を使用していて、ラムダリストがかなり異なる場合は、&オプションパラメータを使用するのではなく、自分の意図を明示的にするために、私は個人的に&キーパラメータを使用する傾向があります。私は後で読みやすさに役立つと思う。

このような何か(私たちはすでにクラスのクラスAとクラスBを持っているふりを)試してみてください。

「メソッドの組み合わせが」から「流れ」にディスパッチロジックために、関与しているので
(defgeneric foo (object &key &allow-other-keys) 
    (:documentation "The generic function. Here is where the docstring is defined.")) 

(defmethod foo ((object class-a) &key &allow-other-keys) 
    (print "Code goes here. We dispatched based on type Class A.")) 

(defmethod foo ((object class-b) &key (x 1) (y 2) &allow-other-keys) 
    (print "Code goes here. We dispatched based on type Class B. We have args X and Y.")) 

その使用可能なメソッドの選択肢がある場合、互換性のないラムダリスト(つまりパラメータリスト)がそのチェーンを壊すようなチェーンのようにメソッド定義を考える必要があります。そのため、具体的にそれらを必要としないメソッド定義には、&のキーと&のallow-other-keysがあります。それらをDEFGENERICとメソッド定義に入れると、クラス-bに基づいてディスパッチするメソッド定義を持つことができます。

私はCommon Lisp初心者ですので、これを塩の穀物で取ってください!

関連する問題