2009-11-17 15 views
10

Sto cercando di ottenere i metadati di tutte le funzioni Clojure incorporate.Clojure: come ottenere i meta-dati delle funzioni?

In previous question Ho imparato che questo può essere ottenuto utilizzando qualcosa come ^#'func_name (ottenere i meta dati dell'oggetto var). Ma non sono riuscito a farlo a livello di codice, dove func-name non è noto in anticipo.

Per esempio cercando di ottenere i metadati dell'ultima funzione in 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} 

Come si può fare? Ho già provato numerose varianti, ma niente ha il trucco.

risposta

8

Si sta cercando meta e 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

Grazie! Infatti,^(ns-resolve 'clojure.core last-func) raggiunge questo – GabiMe

+0

Ho trovato un altro modo per farlo usando la funzione "intern":^(intern' clojure.core last-func) – GabiMe

+1

Questa è una soluzione pericolosa:

user=> (meta (intern 'clojure.core (with-meta 'count :meta :data}))) {:ns #, :name count, :meta :data}
Quindi fai attenzione a dove viene il tuo simbolo. Consiglierei comunque ns-resolve su intern. – kotarak

3

funzioni tecnicamente non possono avere metadati in Clojure attualmente:

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

Tuttavia, Vars che sono destinati a funzioni possono, e sembra che questo è quello che si sta trovando con ns-determinazione. (Meta last-func) funzionerebbe anche. Poiché last-func è la var stessa,^# 'last-func (che è una scorciatoia per (meta (var (quote last-func)))) ha un dereferenziamento var ridondante.

+0

No. (meta last-func) non funziona. Provalo tu stesso e vedi Restituisce nil – GabiMe

+0

'clojure.contrib.ns-utils/vars' restituisce un elenco di simboli piuttosto che un elenco di vars, ecco perché non funziona. –

Problemi correlati