2016-06-13 92 views
2

我有一個函數可以處理函數的元數據。我知道,我可以得到一個功能的元數據的語法如下:如何從變量中獲取函數的元數據

(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 

不工作,如果我只是使用元:

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

因爲它以nil返回不與原始元數據的println函數。

同樣的,當我嘗試用反引號:

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

回答

4

在這種情況下,你正在尋找的信息包含在其中包含的功能,而不是在函數的變種。

如果僅給出容器的內容,則在從該對象中刪除對象之前,無法讀取該對象上寫的內容。

  • 命名空間包含var S和給他們的名字
  • 經銷商也有元數據atached他們談它們所包含的功能。
  • 變量也具有功能。

函數可以包含元數據,但您正在查找的特定元數據位於var的元數據中。

(meta #'symbol-here) 

會在當前命名空間與符號symbol-here相關的變種,然後看着那個對象,並從中獲取元數據。

如果您通過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將自動使用相同的參數調用它所包含的函數並傳回迴應。

+0

那麼,有沒有一種方法來獲取我引用的'println'的原始元數據? –

+0

它取決於你的函數如何被調用。我會將其廣告給答案 –

+0

它被稱爲像我在問題中寫的:'(x println)' –