2012-02-25 5 views
8

Tengo un multimétodo que se especializa en dos parámetros:captura defmethod todo

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

Tener el tipo me permite agrupar los diferentes defmethod pone en conjuntos:

(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) 

Sin embargo, a veces, quiero un catch all o por defecto para uno de los grupos, que se llamaría si ninguno de los otros coincide:

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

Sin embargo, esto no funciona a menos que tag sea realmente :default.

¿Cuál es una buena manera de lograr esto?

Respuesta

7

Su función de despacho necesita saber qué asignaciones ya están definidos para que pueda decidir cuándo recurrir a un valor predeterminado. La función methods le devolverá esas asignaciones.

(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

Se podía alterar la defmulti a:

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

Luego escriba su método como este:

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

No quiero que los defmulti sepan sobre los defmethods que lo usarán. – Brigham

7

métodos múltiples apoyar un método de reserva, identificado utilizando el valor (configurable) :default, si ninguno de los otros métodos partido.

En su caso, usted simplemente añadir:

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

dado tu ejemplo, podría valer la pena señalar que se puede establecer jerarquías utilizando palabras clave Clojure y despacho multimethod conocimiento de dichas jerarquías: http://clojure.org/multimethods

+0

Desafortunadamente, necesito que el comportamiento predeterminado sea diferente para diferentes valores de tipo, y creo que solo se puede definir un ': predeterminado' por método múltiple. – Brigham

Cuestiones relacionadas