2012-02-25 6 views
8

私は2つのパラメータに特化したmultimethodを持っている:defmethodキャッチすべて

(defmethod get-tag-type [::cat 0] [type tag] ::tiger) 
(defmethod get-tag-type [::cat 1] [type tag] ::lion) 
(defmethod get-tag-type [::cat 2] [type tag] ::jaguar) 

(defmethod get-tag-type [::dog 0] [type tag] ::poodle) 
(defmethod get-tag-type [::dog 1] [type tag] ::australian-shepherd) 
(defmethod get-tag-type [::dog 2] [type tag] ::labrador-retriever) 

しかし、時々、私が欲しい:型を有する

(defmulti get-tag-type (fn [type tag] [type tag])) 

は異なるdefmethodがセットに呼び出し、グループに私を可能にいずれかのグループのすべてまたはデフォルトをキャッチします。他のグループが一致しない場合に呼び出されます。

(defmethod get-tag-type [::dog :default] ::mutt) 

ただし、tagが実際に:defaultでないと、これは機能しません。

これを行うにはどうすればよいですか?

答えて

7

あなたのディスパッチ機能はときにそれが決定できるようにすでに定義されているマッピングを知る必要がありますデフォルトに頼っている。 methods関数はそれらのマッピングをあなたに返します。

(defmulti get-tag-type (fn [type tag] 
         (let [mlist (methods get-tag-type)] 
          (if-let [d (get mlist [type tag])] 
          [type tag] 
          [type :default])))) 
0

あなたがにdefmultiを変更することもできます。このようなあなたの方法を書き次に

(defmulti get-tag-type (fn [type tag] 
         (if (= type ::dog) 
          ::dog 
          [type tag]))) 

(defmethod get-tag-type ::dog ::mutt) 
+0

を私はdefmultiがそれを使用するdefmethodsについて知ることを望んでいません。 – Brigham

7

マルチメソッドは、他の方法のどれも一致しない場合、(設定)値:defaultを用いて同定フォールバック方式をサポートしています。あなたがClojureのキーワードを使用して階層を確立できることは注目に値するかもしれない、

(defmethod get-tag-type :default [type tag] 
    (do special behaviour here ...)) 

はあなたの例を考えると、multimethod派遣は、それらの階層理解:あなたのケースでは

は、あなたが単に追加したいhttp://clojure.org/multimethods

+0

残念ながら、タイプの異なる値に対してデフォルトの動作が異なるようにする必要があります。マルチメソッドごとに1つの ':default'しか定義できないと思います。 – Brigham

関連する問題