2010-08-04 8 views
12

In Clojure 1.2RC1, ich möchte eine Funktion basierend auf seinem Namen als Zeichenfolge erhalten und evaluieren.Clojure Resolving-Funktion von String-Name

Funktionsdefinition

(ns my-ns) 

(defn mycar [x] (first x)) 

Die folgende gearbeitet:

((ns-resolve *ns* (symbol "mycar")) '(3 4)) 
((intern *ns* (symbol "mycar")) '(3 4)) 
((eval (symbol "mycar")) '(3 4)) 

aber sie scheinen hässlich. Gibt es einen besseren Weg? Wenn nicht, welches der oben genannten ist am idiomatischsten?

Antwort

13

Dieser arbeitete für mich ohne eval:

user> (defn mycar [x] (first x)) 
#'user/mycar 
user> ((resolve (symbol "mycar")) [1 2 3]) 
1 

Das funktioniert, weil die Entschlüsse mycar var in den aktuellen Namensraum findet und die var ruft die Funktion es gebunden ist. Dies ist eine kürzere Version Ihres ersten Beispiels. Ich würde es nur benutzen, um Eval zu vermeiden.

+1

Ich zweitens die Verwendung von "resolve" oder "ns-resolve". Achten Sie auch auf "intern". Es ist ganz einfach, Dinge damit zu überlisten. – kotarak

+0

Irgendwelche Hinweise zu mehr Informationen über "Clobbering" verursacht durch Intern? – chris

+0

Setzen Sie einen Var mit intern und Ihre ursprünglichen Metadaten auf dem Var werden weg sein. Ignorieren. Scheint behoben zu sein. Zumindest kann ich es nicht mehr reproduzieren. – kotarak