问题
Let's take that Clojure code:
(defn ^{:test-1 "meta-test-1"} fn-key-1
[x]
(eval nil))
(defn ^{:test-2 "meta-test-2"} fn-key-2
[x]
(eval nil))
(def some-map {fn-key-1 "test-1"
fn-key-2 "test-2"})
As you can see, the keys of my map are Symbols that refers to functions. I don't thing there is anything special there.
As you can see, when defining the map the keys of my map are Symbols that refers to functions. However, when they are read by the reader, then they get resolved to the function objects.
Now, what I want to do is to iterate over my some-map
map to get the meta-data for each of the keys.
I was thinking doing this that way:
(defn some-fn
[m]
(doseq [[fn-key value] m]
(println (meta fn-key))))
However, what is being printed here is nil
. This is expected since the meta-data is defining the symbol, and not the function. So, there is no meta-data attached to the function and it is why nil
is being returned/printed.
So this lead to a question: is it possible to get the symbol that refers to my function "fn-key" in that context?
In that doseq loop, it appears that fn-key is a function and not the symbol of that function. What I need is a way to get the symbol of that function such that I can use (meta (get-symbol fn-key)).
Question Resolution
This question got resolved by defining the functions that way:
(def fn-key-1
(with-meta (fn [x] (eval nil)) {:foo "bar"}))
(def fn-key-2
(with-meta (fn [x] (eval nil)) {:foo "bar"}))
Revision of the Resolution
I revised the solution above to make it cleaner. In fact, if you were to type fn-key-1
in the REPL, you were to get an anonymous function reference such as #< clojure.lang.AFunction$1@15ab1764>
. The problem with that is that it make things difficult to debug when you don't know what is being evaluated. To solve this issue, I changed the two function definitions to use this syntax, which resolve this issue:
(def fn-key-1 ^{:foo "bar"} (fn [x] (eval nil)))
(def fn-key-2 ^{:foo "bar"} (fn [x] (eval nil)))
Now, if we type fn-key-1
then we will get something like #<core$foo user.core$foo@66e37466>
instead. At least, we have the namespace & symbol signature of this function object.
回答1:
(def some-map {#'fn-key-1 "test-1"
#'fn-key-2 "test 2"})
fn-key-1
is resolved by the reader to the function object (which has no metadata to query). #'fn-key-1
resolves to the var
itself, and holds the metadata.
来源:https://stackoverflow.com/questions/24000510/clojure-issues-getting-the-symbol-of-a-function-in-a-looping-context