[英]How can I display the definition of a function in Clojure at the REPL?
我正在尋找能夠讓REPL打印出函數的當前定義的能力。 有沒有辦法做到這一點?
例如,給定:
(defn foo [] (if true "true"))
我想說點什么
(print-definition foo)
並得到一些東西
(foo [] (if true "true"))
打印。
source
的替代方法(在啟動REPL時應該通過clojure.repl/source
,從1.2.0
。如果你使用的是1.1.0
或更低版本,則source
在clojure.contrib.repl-utils
。) ,對於REPL使用,而不是查看.clj
文件中定義的函數:
(defmacro defsource
"Similar to clojure.core/defn, but saves the function's definition in the var's
:source meta-data."
{:arglists (:arglists (meta (var defn)))}
[fn-name & defn-stuff]
`(do (defn ~fn-name ~@defn-stuff)
(alter-meta! (var ~fn-name) assoc :source (quote ~&form))
(var ~fn-name)))
(defsource foo [a b] (+ a b))
(:source (meta #'foo))
;; => (defsource foo [a b] (+ a b))
一個簡單的print-definition
:
(defn print-definition [v]
(:source (meta v)))
(print-definition #'foo)
#'
只是一個讀者宏 ,從#'foo
擴展到(var foo)
:
(macroexpand '#'reduce)
;; => (var reduce)
您將要導入repl
名稱空間,並使用它的source
函數:
(ns myns
(:use [clojure.repl :only (source)]))
(defn foo [] (if true "true"))
(source foo)
=> (foo [] (if true "true"))
nil
雖然這在REPL中不起作用,但只能在類路徑上的.clj文件中定義函數。 那么你的問題沒有回答:你需要有一個defn
,它在它定義的fn
的元數據中存儲函數的來源。 然后你會編寫一個函數來回憶那些元數據。 這應該不是非常困難。
Clojure沒有反編譯器,所以這意味着沒有辦法獲得任意函數的源,除非它是從磁盤加載的defn。 但是,您可以使用名為serializable-fn的簡潔hack來創建一個將源代碼存儲在其元數據中的函數: http : //github.com/Seajure/serializable-fn
defsource答案與此非常相似,但此解決方案適用於任意fns,而不僅僅是頂級定義。 它還使fns在repl上打印得漂亮,沒有特殊的打印功能。
在clojure 1.2的REPL中, source
函數立即可用。 你可以這樣使用它:
$ java -cp clojure.jar clojure.main Clojure 1.2.0 user=> (source slurp) (defn slurp "Reads the file named by f using the encoding enc into a string and returns it." {:added "1.0"} ([f & opts] (let [opts (normalize-slurp-opts opts) sb (StringBuilder.)] (with-open [#^java.io.Reader r (apply jio/reader f opts)] (loop [c (.read r)] (if (neg? c) (str sb) (do (.append sb (char c)) (recur (.read r))))))))) nil user=>
其他一些函數也會自動從clojure.repl庫導入REPL的user
命名空間。 請在此處查看API文檔。
但是,正如在此處的其他答案中所指出的,您不能使用source
來打印您在REPL中定義的函數。
我最近在Clojure郵件列表上確切地問了這個問題,答案包括覆蓋REPL的部分以隱藏輸入(和輸出)以備將來參考,以及覆蓋defn以將源存儲在元數據中(然后你可以在REPL中輕松檢索)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.