2011-10-10 3 views
9

Как я могу узнать, является ли имя функции, предоставленное как строка, вызываемой или нет в текущем контексте? что-то вроде:Clojure: определить, существует ли функция

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

благодаря

+0

отметить также слово «отзывные» в настоящее время перегружен здесь. Все функции Clojure - java.util.concurrent.Callables. –

ответ

17

Вы ищете решимость,

(resolve (symbol "asd")) 

возвращает нильполугруппу

(resolve (symbol "filter")) 

возвращение # 'clojure.core/фильтр

Чтобы проверить, если переменная является функцией (Заслуга @amalloy):

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

возвращает то, что вы сказали, но как я могу определить, является ли оно вызываемым или нет? – pistacchio

+0

Вы можете позвонить (fn? (Разрешить (символ «фильтр»))) - я бы рекомендовал это по моему ответу –

+0

@JoostDiepenmaat: в этом случае '(fn? (Eval (symbol" filter ")))' - ' resol' возвращает класс или var, а не что-то с интерфейсом Fn (см. мой ответ) и, следовательно, не будет работать. – ffriend

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

UPD. Я узнал, что fn? проверяет только на интерфейс Fn и не работает для разрешенного символа. Хотя, clojure.test/function? делает то, что необходимо, поэтому я обновил пример.

1

Скорее всего, если вам это нужно, вы делаете что-то неправильно, но ...

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

Augh no. Использование 'resolve' является признаком того, что вы можете сделать что-то неправильно; использование 'eval' для выполнения одной и той же задачи - верный признак того, что вы делаете что-то неправильно. – amalloy

Смежные вопросы