2016-09-17 1 views
1

J'utilise multimethods pour analyser les commandes de ligne de commande et leurs arguments.Comment définir et obtenir des métadonnées multiméthodes dans clojure?

(defmulti run (fn [command args] command)) 

(defmethod run :default 
    [& _] 
    ...) 

^{:args "[command]"} 
(defmethod run "help" 
    [_ & [args]] 
    "Display command list or help for a given command" 
    ...) 

^{:args ""} 
(defmethod run "version" 
    [_ & [args]] 
    "Print program's version" 
    ...) 

(defn -main 
    [& args] 
    (run (first args) 
    (next args))) 

Lorsque je tente d'accéder aux métadonnées, pour une méthode spécifique, Clojure retourne nil:

(meta ((methods run) "help")) 

Répondre

3

Il n'y a pas une telle possibilité. La première raison (simple) est que defmethod ne permet pas de définir des métadonnées pour une méthode particulière (seul defmulti le permet, mais seulement pour l'ensemble du multiméthode). La deuxième raison est que la méthode multiméthode est essentiellement une fonction unique, juste avec plusieurs «variantes» d'exécution, dont chacune se déclenche en fonction des paramètres transmis. À peu prés parler, du point de vue de l'appelant, il n'y a pas de différence particulière entre les fonctions f1 et f2 définies ci-dessous:

(defmulti f1 (fn [x] x)) 

(defmethod f1 :foo [x] 
    ...) 

(defmethod f1 :bar [x] 
    ...) 

(defmethod f1 :baz [x] 
    ...) 

(defn f2 [x] 
    (case x 
    :foo ... 
    :bar ... 
    :baz ...)) 

Personnellement, je considère, selon que la fonction particulière est fonction multiméthode ou ordinaire qu'en se fondant sur les détails de mise en œuvre. Aussi, si vous avez besoin de documenter explicitement chaque méthode de multimehod, vous devriez envisager de remplacer chaque méthode par une fonction ordinaire et de ne pas utiliser de méthodes multiméthodes.