Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A blog entry about requiring all available namespaces.
- Loading branch information
john
committed
Feb 8, 2010
1 parent
1bb9adf
commit 5e37398
Showing
1 changed file
with
79 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
;; It often irritates me that I can't use clojure's built in documentation unless I've already | ||
;; loaded the library I need. | ||
|
||
;; Sometimes it turns out that the generic-looking function I need already exists, but it can be | ||
;; hard to find it. Sometimes I can remember the function I want, but not its precise name or | ||
;; library namespace. | ||
|
||
;; It's also often the case that the best way to understand a function is to read the source. | ||
|
||
;; The other day it occurred to me that a function to find all the namespaces available on the | ||
;; classpath might help quite a bit, and I started to write one. And at that point I had the obvious | ||
;; recursive thought. | ||
|
||
;; Seek and ye shall find. Thank you Stuart Sierra. | ||
(use 'clojure.contrib.find-namespaces) | ||
|
||
;; First let's see what our classpath is: | ||
(println "Classpath") | ||
(doseq [p (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))] (println (str p))) | ||
|
||
;; In my case, that's the clojure.jar and clojure.contrib.jar files, and also the directory | ||
;; containing the files for swank-clojure, the library which allows it to talk to emacs. | ||
(println "Swank namespaces") | ||
(println (for [s (for [n (all-ns)] (name (ns-name n))) :when (. s contains "swank")] s)) | ||
|
||
;; Because I'm still a beginner, and not brave enough to modify swank, I'm more interested in | ||
;; the namespaces provided by clojure and clojure.contrib | ||
|
||
;; So far, the following have managed to get themselves loaded: | ||
(println "None-swank namespaces") | ||
(use 'clojure.contrib.pprint) | ||
(pprint (sort (for [s (for [n (all-ns)] (name (ns-name n))) :when (not (. s contains "swank"))] s))) | ||
|
||
;; But the following are in fact available | ||
(pprint (find-namespaces-on-classpath)) | ||
|
||
;; Again, let's ignore the swank-related ones. | ||
(pprint (filter #(not (. (str %) startsWith "swank")) (find-namespaces-on-classpath))) | ||
|
||
;;For me there are only namespaces starting with either swank or clojure, because I don't have much | ||
;;of a classpath. But it's easy enough to check that. | ||
(defn find-namespaces-starting-with [strng] | ||
(filter #(. (str %) startsWith strng) (find-namespaces-on-classpath))) | ||
|
||
(map count (map find-namespaces-starting-with '("clojure" "swank" ""))) ; should add up | ||
|
||
;; Some of the clojure.contrib libraries fail to load for me, so we have to bullet-proof require | ||
(defn require-may-fail [ns] | ||
(try | ||
(print "Attempting to require " ns ": ") | ||
(require ns) | ||
(println "success") | ||
(catch Exception e (println "couldn't require " ns "\nException\n" e "\n\n")))) | ||
|
||
;; Now we can load everything | ||
(doall (map require-may-fail (filter #(. (str %) startsWith "clojure") (find-namespaces-on-classpath)))) | ||
|
||
;; Now we have lots and lots of namespaces available: The number of 'batteries included' is impressive. | ||
(println "None-swank namespaces") | ||
(pprint (sort (for [s (for [n (all-ns)] (name (ns-name n))) :when (not (. s contains "swank"))] s))) | ||
|
||
;; And the find-doc, doc, and source commands become really useful | ||
;; Of course we not only have to find source, we actually can, now. | ||
(find-doc "source code") | ||
|
||
;; Also note that all this requiring hasn't brought any new functions into play yet. | ||
;; To use something without qualification, you need to refer as well. | ||
(refer 'clojure.contrib.repl-utils) | ||
(doc source) | ||
(source source) | ||
(source get-source) | ||
(:file (meta (resolve 'source))) | ||
|
||
|
||
;; Other sources of enjoyment are the find and grep commands, and browsing clojure.contrib.jar and | ||
;; clojure.jar These work particularly nicely under emacs. A good arrangement of find and grep is | ||
;; (assuming that your clojure sources are under ~/opt): | ||
|
||
;; find ~/opt/ -name "*.clj" -and -type f -print0 | xargs -0 -e grep -nH -e "repl-util" |