如何从变量中获取函数的元数据

时间:2016-06-13 16:03:30

标签: clojure metadata

我有一个可以处理函数元数据的函数。我知道我可以用以下语法获取函数的元数据:

(meta #'println)

返回我感兴趣的元数据:

{:arglists ([& more]), :doc "Same as print followed by (newline)", :added "1.0", :static true, :line 3631, :column 1, :file "clojure/core.clj", :name println, :ns #namespace[clojure.core]}

但如果它在变量中,它就无法工作。我尝试了以下

(defn x [f] (meta #'f))

当然会抛出以下错误:

clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve var: f in this context, compiling:(/var/folders/zs/_8vy14592dncxyj8mcz4jfyc000_9z/T/boot.user1460390749042099586.clj:1:1)
             java.lang.RuntimeException: Unable to resolve var: f in this context

如果我只使用meta:

,则无效
(defn x [f] (meta f))
(x println)

因为它返回nil而不是println函数的原始元数据。

当我尝试使用反引号时也一样:

(defn x [f] (meta `f))

1 个答案:

答案 0 :(得分:5)

在这种情况下,您要查找的信息包含在包含函数的var中,而不是函数中。

如果只给出容器的内容,则无法读取该对象从其中删除之前写入的内容。

  • 名称空间包含var并为其命名
  • vars有关于它们包含的功能的元数据。
  • vars也有功能。

函数可以包含元数据,但您要查找的特定元数据是var上的hte元数据。

(meta #'symbol-here)

在当前名称空间中查找与符号symbol-here关联的var,然后查看该对象并从中获取元数据。

如果你将var本身传递给函数f而不是传递它的内容,那么你可以从该函数中查找元数据:

user> (defn x [f]
        (f "calling f with a string")
        (meta f))
#'user/x
user> (x #'println)
calling f with a string
{:arglists ([& more]), :doc "Same as print followed by (newline)", :added "1.0", :static true, :line 3631, :column 1, :file "clojure/core.clj", :        name println, :ns #namespace[clojure.core]}

这里的重要部分是你传递了实际包含你正在寻找的元数据的对象(var),而不是容器中的对象(函数),值得注意的是,如果你将var调用为一个函数,var将使用相同的参数自动调用它包含的函数并传回响应。