function clojure metadata clojure-contrib

function - ¿Cómo encuentro dinámicamente los metadatos para una función de Clojure?



metadata clojure-contrib (3)

Hay metadatos en la función func-1 , metadatos en Var #''func-1 y metadatos en el símbolo ''func-1 . La macro del lector de Clojure ^ agrega metadatos al símbolo , en el momento de la lectura. La macro defn copia los metadatos del símbolo al Var , en tiempo de compilación.

Antes de Clojure 1.2, las funciones no admitían metadatos. En Clojure 1.2, lo hacen, y defn también copia algunos metadatos Var estándar a la función :

Clojure 1.2.0 user=> (defn ^{:foo :bar} func-1 [] nil) #''user/func-1 user=> (meta func-1) {:ns #<Namespace user>, :name func-1} user=> (meta #''func-1) {:foo :bar, :ns #<Namespace user>, :name func-1, ...

Sin embargo, en las instantáneas actuales de Clojure 1.3, defn no copia ningún metadato a la función:

Clojure 1.3.0-master-SNAPSHOT user=> (defn ^{:foo :bar} func-1 [] nil) #''user/func-1 user=> (meta func-1) nil user=> (meta #''func-1) {:foo :bar, :ns #<Namespace user>, :name func-1, ...

En general, si desea obtener los metadatos de una definición, desea metadatos en el Var .

Digamos que tengo el siguiente código:

(defn ^{:graph-title "Function 1"} func-1 [x] (do-something-with x)) (defn get-graph-title [func] (str ((meta func) :graph-title)))

Espero que esto devuelva "Función 1", pero devuelve nil. Creo que esto se debe a la siguiente diferencia, que no comprendo totalmente:

(meta func-1) => {:ns some-ns-info, :name func-1} (meta #''func-1) => {:ns some-ns-info, :name func-1, :graph-title "Function 1"}

¿Puede alguien explicarme esto?


Los metadatos que especifique en el símbolo func-1 en su código fuente se copian a la var llamada func-1 mediante la forma especial de def. Consulte la documentación para la definición en http://clojure.org/special_forms

Cuando evalúa func-1 donde es un símbolo vinculado a una var, obtiene el valor de la var (que es el objeto de la función en este caso). Ver http://clojure.org/vars

El objeto de función en sí no recibe automáticamente los metadatos especificados manualmente en el símbolo / var.

Por lo tanto, la información que desea no está en la función en absoluto. Está en la var, y debe especificar que realmente desea la var func-1 en lugar de su valor. Eso es lo que hace (var func-1), y el atajo equivalente # ''func-1 lo hace.


Los metadatos se adjuntan a la var, no a la función.

Por lo tanto, para obtener el título del gráfico, debe obtener la entrada :graph-title del meta de la var. ¿Cómo te gustan tus macros?

(defmacro get-graph-title [func] `(:graph-title (meta (var ~func)))) (get-graph-title func-1) => "Function 1"