2011-10-10 17 views
9

¿cómo puedo saber si un nombre de función proporcionado como cadena es invocable o no en el contexto actual? algo así como:Clojure: determine si existe una función

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

gracias

+0

También tenga en cuenta la palabra "exigible" está siendo sobrecargada aquí. Todas las funciones de Clojure son java.util.concurrent.Callables. –

Respuesta

17

Usted está buscando resolver,

(resolve (symbol "asd")) 

devuelve nil

(resolve (symbol "filter")) 

return # 'clojure.core/filter

Para comprobar si un var es una función (el crédito va a @amalloy):

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

devuelve lo que dijo, pero ¿cómo puedo determinar si es invocable o no? – pistacchio

+0

Puede llamar (fn? (Resolver (símbolo "filtro"))) - Lo recomendaría sobre mi respuesta –

+0

@JoostDiepenmaat: en este caso '(fn? (Eval (symbol" filter ")))' - ' resolve' devuelve class o var, no algo con la interfaz 'Fn' (ver mi respuesta) y por lo tanto no funcionará. – ffriend

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

UPD. Descubrí que fn? solo comprueba la interfaz Fn y no funciona para el símbolo resuelto. Aunque, clojure.test/function? hace lo que se necesita, entonces actualicé un ejemplo.

1

Es probable que si usted necesita esto, estás haciendo algo mal, pero ...

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

Augh no. Usar 'resolve' es un signo de que podrías estar haciendo algo mal; usar 'eval' para hacer la misma tarea es un signo seguro de que estás haciendo algo mal. – amalloy

Cuestiones relacionadas