2009-11-17 2 views
10

Я пытаюсь получить метаданные всех встроенных функций Clojure.Clojure: Как получить метаданные функций?

В previous question Я узнал, что это может быть достигнуто с помощью чего-то вроде ^#'func_name (получить метаданные объекта var). Но мне не удалось сделать это программно, где func-name не известно заранее.

Например, пытающегося получить метаданные последней функции в clojure.core:

user=> (use 'clojure.contrib.ns-utils) 
nil 
user=> (def last-func (last (vars clojure.core))) 

user=> last-func 
zipmap 

;The real metadata (zipmap is hardcoded) 
user=> ^#'zipmap 
{:ns #<Namespace clojure.core>, :name zipmap, :file "clojure/core.clj", :line 1661, :arglists ([keys vals]), :doc "Returns a map .."} 

;Try to get programmatically, but get shit 
user=> ^#'last-func 
{:ns #<Namespace user>, :name last-func, :file "NO_SOURCE_PATH", :line 282} 

Как это может быть сделано? Я уже пробовал много вариантов, но ничего не делает.

ответ

8

Вы ищете meta и ns-resolve.

user=> (let [fun "map"] (meta (ns-resolve 'clojure.core (symbol fun)))) 
{:ns #<Namespace clojure.core>, :name map, :file "clojure/core.clj", :line 1705, :arglists ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]), :doc "Returns a lazy sequence consisting of the result of applying f to the\n set of first i tems of each coll, followed by applying f to the set\n of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n f should accept number-of-colls arguments."}
+0

Спасибо! Действительно,^(ns-resolve 'clojure.core last-func) достигает этого – GabiMe

+0

. Я нашел другой способ сделать это, используя функцию «intern»:^(intern' clojure.core last-func) – GabiMe

+1

Это опасное решение:

user=> (meta (intern 'clojure.core (with-meta 'count :meta :data}))) {:ns #, :name count, :meta :data}
Так что будьте осторожны, откуда приходит ваш символ. Я бы по-прежнему рекомендовал ns-resolve для стажера. – kotarak

3

функции Технически не могут иметь метаданные в Clojure в настоящее время:

http://www.assembla.com/spaces/clojure/tickets/94-GC--Issue-90---%09-Support-metadata-on-fns

Однако вары, которые связаны с функциями, может, и, похоже, что это то, что вы находите с Ns-решимостью. (meta last-func) тоже будет работать. Поскольку last-func - это сам var,^# 'last-func (который является сокращением для (meta (var (quote last-func)))) имеет избыточное разграничение var.

+0

№ (meta last-func) не работает. Попробуйте сами и посмотрите. Он возвращает nil – GabiMe

+0

'clojure.contrib.ns-utils/vars' возвращает список символов, а не список варов, поэтому он не работает. –

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