On Sun, Nov 2, 2008 at 6:34 PM, Mark McGranaghan <[EMAIL PROTECTED]> wrote:
>
> I really like being able to find and check documentation in the REPL
> with find-doc and doc, but I often would like to see the source code
> of a function or macro to be able to understand it better or learn
> from the implementation.

(import '(java.io LineNumberReader InputStreamReader PushbackReader)
        '(clojure.lang RT))

(defn get-source [vn]
  (let [m ^(resolve vn)
        strm (.getResourceAsStream (RT/baseLoader) (str "clojure/" (:file m)))]
    (if (and m strm)
      (with-open rdr (LineNumberReader. (InputStreamReader. strm))
        (dotimes _ (dec (:line m)) (.readLine rdr))
        (.mark rdr 2000)
        (read (PushbackReader. rdr))
        (let [cnt (- (.getLineNumber rdr) (:line m))]
          (.reset rdr)
          (dotimes _ cnt (println (.readLine rdr)))
          true))
      (println "Source not found for" vn))))

(defmacro source [n]
  `(get-source '~n))

It's not pretty, and it only works on functions defined in the clojure
namespace.  But it does work, without requiring any changes to Clojure
itself:

user=> (source filter)
(defn filter
  "Returns a lazy seq of the items in coll for which
  (pred item) returns true. pred must be free of side-effects."
  [pred coll]
    (when (seq coll)
      (if (pred (first coll))
true

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to