如何动态查找Clojure函数的元数据?

fun*_*nky 17 metadata function clojure clojure-contrib

说我有以下代码:

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

(defn get-graph-title 
  [func]
  (str
    ((meta func) :graph-title))) 

我希望这会返回"功能1",但它返回nil.我认为这源于以下差异,我不完全理解:

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

谁可以给我解释一下这个?

Stu*_*rra 31

有关函数的 func-1元数据,Var #'func-1上的元数据和符号 上的元数据'func-1.Clojure的读者宏^添加元数据的符号,在读取时间.在defn从宏复制元数据符号无功,在编译时.

在Clojure 1.2之前,函数不支持元数据.在Clojure 1.2中,他们这样做,并且defn还将一些标准的Var元数据复制到该函数中:

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, ...
Run Code Online (Sandbox Code Playgroud)

但是,在当前的Clojure 1.3快照中,defn不会将任何元数据复制到该函数:

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, ...
Run Code Online (Sandbox Code Playgroud)

通常,如果要获取定义的元数据,则需要Var上的元数据.


Leo*_*nel 19

元数据附加到var,而不是函数.

因此,要获得图形标题,您必须:graph-title从var的元数据中获取条目.你觉得你的宏怎么样?

(defmacro get-graph-title
  [func]
  `(:graph-title (meta (var ~func))))

(get-graph-title func-1)
=> "Function 1"
Run Code Online (Sandbox Code Playgroud)

  • 或者只是使用当前的定义并执行(get-graph-title#'func-1) (4认同)