2011-10-10 11 views
9

come posso sapere se un nome di funzione fornito come stringa è richiamabile o meno nel contesto corrente? qualcosa di simile:Clojure: determina se esiste una funzione

(callable? "asdasd") ;; false 
(callable? "filter") ;; true 

grazie

+0

Da notare anche la parola "callable" viene sovraccaricato qui. Tutte le funzioni di Clojure sono java.util.concurrent.Callables. –

risposta

17

Ricercate risolutezza,

(resolve (symbol "asd")) 

ritorna nil

(resolve (symbol "filter")) 

return # 'clojure.core/filter

Per verificare se un var è una funzione (il merito va a @amalloy):

(-> s symbol resolve deref ifn?) 
+1

restituisce ciò che hai detto, ma come posso determinare se è richiamabile o no? – pistacchio

+0

Puoi chiamare (fn? (Risolvere (simbolo "filtro"))) - Lo raccomanderei sopra la mia risposta –

+0

@JoostDiepenmaat: in questo caso '(fn? (Eval (simbolo" filtro ")))' - ' resolve' restituisce class o var, non qualcosa con l'interfaccia 'Fn' (vedi la mia risposta) e quindi non funzionerà. – ffriend

-1
(defn callable? [name]  
    (clojure.test/function? (symbol name))) 

UPD. Ho scoperto che fn? controlla solo per l'interfaccia Fn e non funziona per il simbolo risolto. Sebbene, clojure.test/function? faccia ciò che è necessario, così ho aggiornato un esempio.

1

è probabile che se avete bisogno di questo, si sta facendo qualcosa di sbagliato, ma ...

(defn callable? 
    [s] 
    (let [obj (try (eval (symbol s)) (catch Exception e))] 
    (and obj (fn? obj)))) 
+4

Augh no. Usare 'resolve' è un segno che potresti fare qualcosa di sbagliato; usare 'eval' per fare lo stesso compito è un segno sicuro che stai facendo qualcosa di sbagliato. – amalloy

Problemi correlati