Say I have the following code:
说我有以下代码:
(defn ^{:graph-title "Function 1"} func-1 [x] (do-something-with x)) (defn get-graph-title [func] (str ((meta func) :graph-title)))
I expect this to return "Function 1", but it returns nil. I think this stems from the following difference, which I don't totally comprehend:
我希望这会返回“Function 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"}
Can someone explain this to me?
谁可以给我解释一下这个?
3 个解决方案
#1
18
The metadata is attached to the var, not to the function.
元数据附加到var,而不是函数。
Thus, to get the graph title, you have to get the entry :graph-title
from the meta of the var. How do you like your macros ?
因此,要获得图形标题,您必须从var的元数据中获取条目:graph-title。你觉得你的宏怎么样?
(defmacro get-graph-title
[func]
`(:graph-title (meta (var ~func))))
(get-graph-title func-1)
=> "Function 1"
#2
30
There's metadata on the function func-1
, metadata on the Var #'func-1
, and metadata on the symbol 'func-1
. The Clojure reader macro ^
adds metadata to the symbol, at read time. The defn
macro copies metadata from the symbol to the Var, at compile time.
关于函数func-1的元数据,Var#'func-1上的元数据以及符号'func-1上的元数据。 Clojure读取器宏^在读取时将元数据添加到符号。 defn宏在编译时将元数据从符号复制到Var。
Prior to Clojure 1.2, functions did not support metadata. In Clojure 1.2, they do, and defn
also copies some standard Var metadata to the function:
在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, ...
However, in current Clojure 1.3 snapshots, defn
does not copy any metadata to the function:
但是,在当前的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, ...
In general, if you want to get at the metadata of a definition, you want metadata on the Var.
通常,如果要获取定义的元数据,则需要Var上的元数据。
#3
2
The metadata you specify on the symbol func-1 in your source code is copied to the var named func-1 by the def special form. See the documentation for def in http://clojure.org/special_forms
您在源代码中的符号func-1上指定的元数据将通过def特殊形式复制到名为func-1的var中。请参阅http://clojure.org/special_forms中的def文档
When you evaluate func-1
where that's a symbol bound to a var, you get the value of the var (which is the function object in this case). See http://clojure.org/vars
当你评估func-1这是一个绑定到var的符号时,你得到var的值(在这种情况下是函数对象)。见http://clojure.org/vars
The function object itself does not automatically recieve the metadata manually specified on the symbol / var.
函数对象本身不会自动接收符号/ var上手动指定的元数据。
So, the information you want is not in the function at all. It's in the var, and you have to specify that you really want the var func-1
itself instead of its value. That's what (var func-1), and the equivalent short-cut #'func-1 does.
因此,您想要的信息根本不在功能中。它在var中,你必须指定你真的想要var func-1本身而不是它的值。这就是(var func-1)和等效的快捷方式#'func-1。
#1
18
The metadata is attached to the var, not to the function.
元数据附加到var,而不是函数。
Thus, to get the graph title, you have to get the entry :graph-title
from the meta of the var. How do you like your macros ?
因此,要获得图形标题,您必须从var的元数据中获取条目:graph-title。你觉得你的宏怎么样?
(defmacro get-graph-title
[func]
`(:graph-title (meta (var ~func))))
(get-graph-title func-1)
=> "Function 1"
#2
30
There's metadata on the function func-1
, metadata on the Var #'func-1
, and metadata on the symbol 'func-1
. The Clojure reader macro ^
adds metadata to the symbol, at read time. The defn
macro copies metadata from the symbol to the Var, at compile time.
关于函数func-1的元数据,Var#'func-1上的元数据以及符号'func-1上的元数据。 Clojure读取器宏^在读取时将元数据添加到符号。 defn宏在编译时将元数据从符号复制到Var。
Prior to Clojure 1.2, functions did not support metadata. In Clojure 1.2, they do, and defn
also copies some standard Var metadata to the function:
在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, ...
However, in current Clojure 1.3 snapshots, defn
does not copy any metadata to the function:
但是,在当前的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, ...
In general, if you want to get at the metadata of a definition, you want metadata on the Var.
通常,如果要获取定义的元数据,则需要Var上的元数据。
#3
2
The metadata you specify on the symbol func-1 in your source code is copied to the var named func-1 by the def special form. See the documentation for def in http://clojure.org/special_forms
您在源代码中的符号func-1上指定的元数据将通过def特殊形式复制到名为func-1的var中。请参阅http://clojure.org/special_forms中的def文档
When you evaluate func-1
where that's a symbol bound to a var, you get the value of the var (which is the function object in this case). See http://clojure.org/vars
当你评估func-1这是一个绑定到var的符号时,你得到var的值(在这种情况下是函数对象)。见http://clojure.org/vars
The function object itself does not automatically recieve the metadata manually specified on the symbol / var.
函数对象本身不会自动接收符号/ var上手动指定的元数据。
So, the information you want is not in the function at all. It's in the var, and you have to specify that you really want the var func-1
itself instead of its value. That's what (var func-1), and the equivalent short-cut #'func-1 does.
因此,您想要的信息根本不在功能中。它在var中,你必须指定你真的想要var func-1本身而不是它的值。这就是(var func-1)和等效的快捷方式#'func-1。