An alternative to source
(which should be available when starting a REPL, as of 1.2.0
. If not, it's in clojure.repl
. If you're working with 1.1.0
or lower, source
is in clojure.contrib.repl-utils
.), for REPL use, instead of looking at functions defined in a .clj
file:
(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))
If you wanted the above to show (defn foo [a b] (+ a b))
, you could use:(clojure.walk/postwalk-replace {'defsource 'defn} (:source (meta #'foo)))
. (you'd probably put this in defsource
, or at least in print-definition
, though. I wouldn't do either.)
A simple print-definition
:
(defn print-definition [v]
(:source (meta v)))
(print-definition #'foo)
#'
is just a reader macro, expanding from #'foo
to (var foo)
:
(macroexpand '#'reduce)
;; => (var reduce)