diff options
-rw-r--r-- | Revisions | 7 | ||||
-rw-r--r-- | def.clj | 74 | ||||
-rw-r--r-- | duck-streams.clj | 120 | ||||
-rw-r--r-- | enum.clj | 47 | ||||
-rw-r--r-- | except.clj | 44 | ||||
-rw-r--r-- | fcase.clj | 93 | ||||
-rw-r--r-- | import-static.clj | 60 | ||||
-rw-r--r-- | javalog.clj | 98 | ||||
-rw-r--r-- | lazy-seqs.clj | 90 | ||||
-rw-r--r-- | lib.clj | 351 | ||||
-rw-r--r-- | memoize.clj | 32 | ||||
-rw-r--r-- | ns-utils.clj | 88 | ||||
-rw-r--r-- | pred.clj | 108 | ||||
-rw-r--r-- | seq-utils.clj | 54 | ||||
-rw-r--r-- | sql.clj | 126 | ||||
-rw-r--r-- | str-utils.clj | 44 | ||||
-rw-r--r-- | string.clj | 29 | ||||
-rw-r--r-- | test-is.clj | 211 | ||||
-rw-r--r-- | trace.clj | 55 |
19 files changed, 7 insertions, 1724 deletions
diff --git a/Revisions b/Revisions new file mode 100644 index 00000000..65f2cf00 --- /dev/null +++ b/Revisions @@ -0,0 +1,7 @@ +2008-08-16 All namespace-directory-aware libs have been moved to +src/clojure/contrib. Please udpate your clojure classpaths accordingly. + +2008-08-16 Revision 134 is the last to contain +non-namespace-directory-aware libs at the top level of this repository. At +the time of this writing, Clojure's SVN version is 1001. + diff --git a/def.clj b/def.clj deleted file mode 100644 index 367d1fda..00000000 --- a/def.clj +++ /dev/null @@ -1,74 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; File: def.clj -;; -;; def.clj provides variants of def that make including doc strings and -;; making private definitions more succinct. -;; -;; scgilardi (gmail) -;; 17 May 2008 - -(clojure/in-ns 'def) -(clojure/refer 'clojure) - -(defmacro init-once - "Initializes a var exactly once. The var must already exist." - [var init] - `(let [v# (resolve '~var)] - (when-not (.isBound v#) - (.bindRoot v# ~init)))) - -(defmacro defvar - "Defines a var with an optional intializer and doc string" - ([name] - (list `def name)) - ([name init] - (list `def name init)) - ([name init doc] - (list `def (with-meta name (assoc (meta name) :doc doc)) init))) - -(defmacro defunbound - "Defines an unbound var with optional doc string" - ([name] - (list `def name)) - ([name doc] - (list `def (with-meta name (assoc (meta name) :doc doc))))) - -(defmacro defmacro- - "Same as defmacro but yields a private definition" - [name & decls] - (list* `defmacro (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defvar- - "Same as defvar but yields a private definition" - [name & decls] - (list* `defvar (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defunbound- - "Same as defunbound but yields a private definition" - [name & decls] - (list* `defunbound (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defstruct- - "Same as defstruct but yields a private definition" - [name & decls] - (list* `defstruct (with-meta name (assoc (meta name) :private true)) decls)) - -(defmacro defalias - "Defines an alias for a var: a new var with the same value and metadata - as another with the exception of :namespace, :name, :file, :line, and - optionally :doc which are those of new var." - ([name orig] - `(let [v# (def ~name ~orig)] - (. v# (setMeta (merge (meta #'~orig) (meta #'~name)))) - v#)) - ([name orig doc] - `(let [v# (def ~name ~orig)] - (. v# (setMeta (merge (meta #'~orig) (assoc (meta #'~name) :doc ~doc)))) - v#))) diff --git a/duck-streams.clj b/duck-streams.clj deleted file mode 100644 index 5c6cba09..00000000 --- a/duck-streams.clj +++ /dev/null @@ -1,120 +0,0 @@ -;;; duck-streams.clj -- duck-typed I/O streams for Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 8, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -;; This file defines "duck-typed" I/O utility functions for Clojure. -;; The 'reader' and 'writer' functions will open and return an -;; instance of java.io.BufferedReader and java.io.PrintWriter, -;; respectively, for a variety of argument types -- filenames as -;; strings, URLs, java.io.File's, etc. These functions are not very -;; efficient, because they have to perform a number of 'instance?' -;; checks, but they are convenient when you just want to open a file -;; and don't want to deal with all the Java I/O classes. -;; -;; This file also defines two convenience functions, 'spit' (opposite -;; of 'slurp') and 'write-lines' (opposite of 'line-seq'). - - -(clojure/in-ns 'duck-streams) -(clojure/refer 'clojure) - -(import '(java.io Reader InputStream InputStreamReader FileReader - BufferedReader File PrintWriter OutputStream - OutputStreamWriter BufferedWriter Writer FileWriter) - '(java.net URI URL MalformedURLException)) - -(defmacro bufr - {:private true} - [reader] - `(new java.io.BufferedReader ~reader)) - -(defn reader - "Attempts to coerce its argument into an open - java.io.BufferedReader. Argument may be an instance of Reader, - BufferedReader, InputStream, File, URI, URL, or String. - - If argument is a String, it tries to resolve it first as a URI, then - as a local file name. URIs with a 'file' protocol are converted to - local file names. - - Should be used inside with-open to ensure the Reader is properly - closed." - [x] - (cond - (instance? BufferedReader x) x - (instance? Reader x) (bufr x) - (instance? InputStream x) (bufr (new InputStreamReader x)) - (instance? File x) (bufr (new FileReader #^File x)) - (instance? URL x) (if (= (. #^URL x (getProtocol)) "file") - (bufr (new FileReader (. #^URL x (getPath)))) - (bufr (new InputStreamReader (. #^URL x (openStream))))) - (instance? URI x) (reader (. #^URI x (toURL))) - (instance? String x) (try (let [url (new URL x)] - (reader url)) - (catch MalformedURLException err - (bufr (new FileReader #^String x)))) - :else (throw (new Exception (str "Cannot coerce " (class x) - " into a Reader."))))) - -(defmacro bufw - {:private true} - [writer] - `(new java.io.PrintWriter (new java.io.BufferedWriter ~writer))) - -(defn writer - "Attempts to coerce its argument into an open java.io.PrintWriter - wrapped around a java.io.BufferedWriter. Argument may be an - instance of Writer, PrintWriter, BufferedWriter, OutputStream, File, - URI, URL, or String. - - If argument is a String, it tries to resolve it first as a URI, then - as a local file name. URIs with a 'file' protocol are converted to - local file names. - - Should be used inside with-open to ensure the Writer is properly - closed." - [x] - (cond - (instance? PrintWriter x) x - (instance? BufferedWriter x) (new PrintWriter #^BufferedWriter x) - (instance? Writer x) (bufw x) ; includes FileWriter - (instance? OutputStream x) (bufw (new OutputStreamWriter x)) - (instance? File x) (bufw (new FileWriter #^File x)) - (instance? URL x) (if (= (. #^URL x (getProtocol)) "file") - (bufw (new FileWriter (. #^URL x (getPath)))) - (throw (new Exception (str "Cannot write to non-file URL <" x ">.")))) - (instance? URI x) (writer (. #^URI x (toURL))) - (instance? String x) (try (let [url (new URL x)] - (writer url)) - (catch MalformedURLException err - (bufw (new FileWriter #^String x)))) - :else (throw (new Exception (str "Cannot coerce " (class x) - " into a Writer."))))) - -(defn write-lines - "Opposite of 'line-seq'. Writes lines (a seq) to writer (an open - java.io.PrintWriter), separated by newlines." - [#^PrintWriter writer lines] - (let [line (first lines)] - (when line - (. writer (write (str line))) - (. writer (println)) - (recur writer (rest lines))))) - -(defn spit - "Opposite of 'slurp'. Writes 'contents' to the file named by - 'filename'." - [filename contents] - (with-open w (#^PrintWriter writer filename) - (. w (print contents)))) - diff --git a/enum.clj b/enum.clj deleted file mode 100644 index f8aa5dc4..00000000 --- a/enum.clj +++ /dev/null @@ -1,47 +0,0 @@ -;;; enum.clj -- Java enum classes in Clojure - -;; by Stuart Sierra, http://www.stuartsierra.com/ -;; May 29, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -;; This file helps define Java Enums, introduced in Java 1.5. Use it -;; when you need to define an enum to pass to a Java method. -;; -;; This file depends on genclass.clj in the Clojure distribution. - - -(clojure/in-ns 'enum) -(clojure/refer 'clojure) - -(defmacro defenum - "Generates and loads a subclass of java.lang.Enum, then - defs symbols as enumerated instances of that class. - - Example: (defenum my.package.MyEnum FOO BAR) - ;; FOO and BAR are now instances of MyEnum - - Java equivalent: enum MyEnum { FOO, BAR }; - - Caveats: - 1. The generated class has no values() method. - 2. The generated class returns false for Class.isEnum(). - 3. Enum.valueOf(Class, String) will not work. - 4. Redefining an enum is allowed, but enumeration resets - to zero." - [class & symbols] - ;; Can't load a class twice, so check first: - (try (. Class (forName (str class))) - (catch java.lang.ClassNotFoundException e - (gen-and-load-class (str class) :extends java.lang.Enum))) - (cons 'do - (map (fn [sym val] - `(def ~sym (new ~class ~(str sym) ~val))) - symbols (iterate inc 0)))) diff --git a/except.clj b/except.clj deleted file mode 100644 index e89246cb..00000000 --- a/except.clj +++ /dev/null @@ -1,44 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and -;; distribution terms for this software are covered by the Common Public -;; License 1.0 (http://opensource.org/licenses/cpl.php) which can be found -;; in the file CPL.TXT at the root of this distribution. By using this -;; software in any fashion, you are agreeing to be bound by the terms of -;; this license. You must not remove this notice, or any other, from this -;; software. -;; -;; except.clj -;; -;; scgilardi (gmail) -;; Created 07 July 2008 - -(clojure/in-ns 'except) -(clojure/refer 'clojure) - -(lib/use string) - -(defn throw-if - "Throws an exception with a message if pred is true. Arguments are: - - pred class? format format-args* - - class is optional and defaults to Exception. If present, it must be a - Class in the tree under Throwable with a constructor that takes a single - String. - - format is a string as documented for java.util.Formatter. - - format-args are zero or more objects that correspond to the format - specifiers in format." - [pred & args] - (if pred - (let [class-present (instance? Class (first args)) - args (if class-present args (cons Exception args)) - [class fmt & fmt-args] args - ctor (.getConstructor (identity class) (into-array [String])) - message (apply format fmt fmt-args) - exception (.newInstance ctor (into-array [message])) - raw-trace (.getStackTrace exception) - boring? #(not= (.getMethodName %) "doInvoke") - trace (into-array (drop 2 (drop-while boring? raw-trace)))] - (.setStackTrace exception trace) - (throw exception)))) diff --git a/fcase.clj b/fcase.clj deleted file mode 100644 index 77018f1a..00000000 --- a/fcase.clj +++ /dev/null @@ -1,93 +0,0 @@ -;;; fcase.clj -- simple variants of "case" for Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 7, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -;; This file defines a generic "case" macro called "fcase" which takes -;; the equality-testing function as an argument. It also defines a -;; traditional "case" macro that tests using "=" and variants that -;; test for regular expressions and class membership. - - -(clojure/in-ns 'fcase) -(clojure/refer 'clojure) - - -(defmacro fcase - "Generic switch/case macro. 'fcase' is short for 'function case'. - - The 'compare-fn' is a fn of two arguments. - - The 'test-expr-clauses' are value-expression pairs without - surrounding parentheses, like in Clojure's 'cond'. - - The 'case-value' is evaluated once and cached. Then, 'compare-fn' - is called once for each clause, with the clause's test value as its - first argument and 'case-value' as its second argument. If - 'compare-fn' returns logical true, the clause's expression is - evaluated and returned. If 'compare-fn' returns false/nil, we go to - the next test value. - - If 'test-expr-clauses' contains an odd number of items, the last - item is the default expression evaluated if no case-value matches. - If there is no default expression and no case-value matches, fcase - returns nil. - - See specific forms of this macro in 'case' and 're-case'. - - The test expressions in 'fcase' are always evaluated linearly, in - order. For a large number of case expressions it may be more - efficient to use a hash lookup." - [compare-fn case-value & - test-expr-clauses] - (let [test-val-sym (gensym "test_val") - test-fn-sym (gensym "test_fn") - cond-loop (fn this [clauses] - (cond - (>= (count clauses) 2) - (list 'if (list test-fn-sym (first clauses) test-val-sym) - (second clauses) - (this (rest (rest clauses)))) - (= (count clauses) 1) (first clauses)))] - (list 'let [test-val-sym case-value, test-fn-sym compare-fn] - (cond-loop test-expr-clauses)))) - -(defmacro case - "Like cond, but test-value is compared against the value of each - test expression with =. If they are equal, executes the \"body\" - expression. Optional last expression is executed if none of the - test expressions match." - [test-value & clauses] - `(fcase = ~test-value ~@clauses)) - -(defmacro re-case - "Like case, but the test expressions are regular expressions, tested - with re-find." - [test-value & clauses] - `(fcase re-find ~test-value ~@clauses)) - -(defmacro instance-case - "Like case, but the test expressions are Java class names, tested with - 'instance?'." - [test-value & clauses] - `(fcase instance? ~test-value ~@clauses)) - -(defn- in-case-test [test-seq case-value] - (some (fn [item] (= item case-value)) - test-seq)) - -(defmacro in-case - "Like case, but test expressions are sequences. The test expression - is true if any item in the sequence is equal (tested with '=') to - the test value." - [test-value & clauses] - `(fcase in-case-test ~test-value ~@clauses)) diff --git a/import-static.clj b/import-static.clj deleted file mode 100644 index b26132e9..00000000 --- a/import-static.clj +++ /dev/null @@ -1,60 +0,0 @@ -;;; import-static.clj -- import static Java methods/fields into Clojure - -;; by Stuart Sierra, http://stuartsierra.com/ -;; June 1, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - - -(clojure/in-ns 'import-static) -(clojure/refer 'clojure) - -(defmacro import-static - "Imports the named static fields and/or static methods of the class - as (private) symbols in the current namespace. - - Example: - user=> (import-static java.lang.Math PI sqrt) - nil - user=> PI - 3.141592653589793 - user=> (sqrt 16) - 4.0 - - Note: The class name must be fully qualified, even if it has already - been imported. Static methods are defined as MACROS, not - first-class fns." - [class & fields-and-methods] - (let [only (set (map str fields-and-methods)) - the-class (. Class forName (str class)) - static? (fn [x] - (. java.lang.reflect.Modifier - (isStatic (. x (getModifiers))))) - statics (fn [array] - (set (map (memfn getName) - (filter static? array)))) - all-fields (statics (. the-class (getFields))) - all-methods (statics (. the-class (getMethods))) - fields-to-do (set/intersection all-fields only) - methods-to-do (set/intersection all-methods only) - make-sym (fn [string] - (with-meta (symbol string) {:private true})) - import-field (fn [name] - (list 'def (make-sym name) - (list '. class (symbol name)))) - import-method (fn [name] - (list 'defmacro (make-sym name) - '[& args] - (list 'list ''. (list 'quote class) - (list 'apply 'list - (list 'quote (symbol name)) - 'args))))] - `(do ~@(map import-field fields-to-do) - ~@(map import-method methods-to-do)))) diff --git a/javalog.clj b/javalog.clj deleted file mode 100644 index 97554886..00000000 --- a/javalog.clj +++ /dev/null @@ -1,98 +0,0 @@ -;;; javalog.clj -- convenient access to java.util.logging in Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 8, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -;; This file defines some convenience functions for using the Java -;; logging framework from Clojure. It is oriented towards simple -;; development and debugging rather than complex production -;; environments. - - - -(clojure/in-ns 'javalog) -(clojure/refer 'clojure) - -(import '(java.util.logging Logger Level ConsoleHandler - FileHandler SimpleFormatter)) - -(def - #^{:tag Logger - :doc "The current java.util.logging.Logger. By default, the - global logger, modified by 'with-logger'."} - *logger* - (. Logger - (getLogger - (. Logger GLOBAL_LOGGER_NAME)))) - -(defmacro log-level - "Translates 'level' (a lower-case keyword) into a static field of - java.util.logging.Level, by name. - - Example: (log-level :severe) => java.util.logging.Level.SEVERE - - If 'level' is not a keyword, it is assumed to be a user-defined - instance of java.util.logging.Level and is returned unchanged." - [level] - (if (keyword? level) - `(. java.util.logging.Level - ~(symbol (. (name level) (toUpperCase)))) - level)) - -(defn root-logger - "Returns the root Logger instance." - ([] (root-logger *logger*)) - ([logger] (let [parent (. logger (getParent))] - (if parent - (recur parent) - logger)))) - -(defn set-console-log-level - "Attempts to set the level of the current logger and the root - ConsoleHandler to 'level' (a java.util.logging.Level). Useful for - debugging at the REPL." - [level] - (let [console-handler - (some (fn [h] (if (instance? ConsoleHandler h) h)) - (. (root-logger) (getHandlers)))] - (if console-handler - (do (. *logger* (setLevel level)) - (. console-handler (setLevel level))) - (throw (new Exception "No ConsoleHandler on root logger."))))) - -(defn add-log-file - "Attaches a log file, using SimpleFormatter, with the given level, - to the named logger. 'level' defaults to ALL. Note: multiple - invocations will create multiple log files, with numbers appended to - the names." - ([logger-name filename] - (add-log-file logger-name filename (. Level ALL))) - ([logger-name filename level] - (let [logger (. Logger (getLogger logger-name)) - handler (new FileHandler filename)] - (. handler (setFormatter (new SimpleFormatter))) - (. handler (setLevel level)) - (. logger (addHandler handler))))) - -(defmacro with-logger - "Executes 'body' with *logger* bound to a logger with the given name - and level. 'level' is expanded with 'log-level'." - [logger-name level & body] - `(binding [*logger* (. Logger (getLogger ~logger-name))] - (. *logger* (setLevel (log-level ~level))) - ~@body)) - -(defmacro log - "Logs a message to *logger*. 'level' is expanded with 'log-level'. - Example: (log :severe \"Bad argument: \" object)" - [level & strings] - `(. *logger* (log (log-level ~level) (str ~@strings)))) diff --git a/lazy-seqs.clj b/lazy-seqs.clj deleted file mode 100644 index 7891bcfa..00000000 --- a/lazy-seqs.clj +++ /dev/null @@ -1,90 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and -;; distribution terms for this software are covered by the Common Public -;; License 1.0 (http://opensource.org/licenses/cpl.php) which can be found -;; in the file CPL.TXT at the root of this distribution. By using this -;; software in any fashion, you are agreeing to be bound by the terms of -;; this license. You must not remove this notice, or any other, from this -;; software. -;; -;; lazy-seqs.clj -;; -;; == Lazy sequences == -;; -;; primes - based on the "naive" implemention described in [1] plus a -;; small "wheel" which eliminates multiples of 2, 3, 5, and -;; 7 from consideration by incrementing past them. Also inspired -;; by code from Christophe Grand in [2]. -;; -;; fibs - based on code from Rich Hickey at the Clojure wiki [3] -;; -;; powers-of-2 - all the powers of 2 -;; -;; == Lazy sequence functions == -;; -;; rotations - returns a lazy seq of all the rotations of a seq -;; -;; permutations - returns a lazy seq of all the permutations of a seq -;; -;; [1] http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf -;; [2] http://clj-me.blogspot.com/2008/06/primes.html -;; [3] http://en.wikibooks.org/wiki/Clojure_Programming#Examples -;; -;; scgilardi (gmail) -;; Created 07 June 2008 - -(clojure/in-ns 'lazy-seqs) -(clojure/refer 'clojure) - -(lib/use def) - -(defvar primes - (lazy-cat [2 3 5 7] - (let [primes-from - (fn primes-from [n [f & r]] - (if (some #(zero? (rem n %)) - (take-while #(<= (* % %) n) primes)) - (recur (+ n f) r) - (lazy-cons n (primes-from (+ n f) r)))) - wheel (cycle [2 4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 - 6 4 6 8 4 2 4 2 4 8 6 4 6 2 4 6 - 2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10])] - (primes-from 11 wheel))) - "A lazy sequence of all the prime numbers.") - -(defvar fibs - (lazy-cat [0 1] - (let [rest-fn - (fn rest-fn [a b] - (let [next (+ a b)] - (lazy-cons next (rest-fn b next))))] - (rest-fn 0 1))) - "A lazy sequence of all the fibonacci numbers.") - -(defvar powers-of-2 - (lazy-cons 1 - (let [rest-fn - (fn rest-fn [n] - (let [next (bit-shift-left n 1)] - (lazy-cons next (rest-fn next))))] - (rest-fn 1))) - "A lazy sequence of all the powers of 2") - -(defn rotations - "Returns a lazy seq of all rotations of a seq" - [x] - (if (seq x) - (map - (fn [n _] - (lazy-cat (drop n x) (take n x))) - (iterate inc 0) x) - (list nil))) - -(defn permutations - "Returns a lazy seq of all permutations of a seq" - [x] - (if (seq x) - (mapcat - (fn [[f & r]] - (map #(cons f %) (permutations r))) - (rotations x)) - (list nil))) diff --git a/lib.clj b/lib.clj deleted file mode 100644 index 186be509..00000000 --- a/lib.clj +++ /dev/null @@ -1,351 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. The use and -;; distribution terms for this software are covered by the Common Public -;; License 1.0 (http://opensource.org/licenses/cpl.php) which can be found -;; in the file CPL.TXT at the root of this distribution. By using this -;; software in any fashion, you are agreeing to be bound by the terms of -;; this license. You must not remove this notice, or any other, from this -;; software. -;; -;; File: lib.clj -;; -;; lib.clj provides facilities for loading and managing libs. A lib is a -;; unit of Clojure code contained in a file or other resource within -;; classpath. Lib names must be valid Clojure symbol names. The name of a -;; lib's container is the lib name followed by ".clj". lib.clj also -;; provides general functions for finding and loading resources using the -;; class loaders visible to the Clojure runtime. -;; -;; Here is a brief overview of what's in lib.clj. For detailed docs please -;; see the doc strings for the individual functions and macros. -;; -;; Resources -;; -;; Function: find-resource -;; Searches available class loaders for a resource, returns URL or nil -;; -;; Function: load-resource -;; Loads Clojure source from an absolute path: URI, URL or String -;; -;; Core -;; -;; Function: load-libs -;; Loads lib(s) based libspecs and flags -;; -;; Function: libs -;; Returns a sorted set of symbols naming the currently loaded libs -;; -;; Convenience -;; -;; Macro: require -;; Loads libs. By default doesn't reload any that are already loaded -;; -;; Macro: use -;; Loads libs like require and refers to each lib's namespace -;; -;; Examples -;; -;; (load-libs :require 'sql '(sql-test :in "private/unit-tests")) -;; (require sql (sql-test :in "private/unit-tests")) -;; -;; (load-libs :require :use 'sql 'ns-utils :verbose) -;; (use sql ns-utils :verbose) -;; -;; (use :reload-all :verbose -;; (sql :exclude '(get-connection) -;; :rename '{execute-commands do-commands}) -;; ns-utils) -;; -;; (use (sql)) -;; -;; (load-libs :require :use '(genclass :ns 'clojure)) -;; (use (genclass :ns 'clojure)) -;; -;; scgilardi (gmail) -;; Created 7 April 2008 -;; -;; Thanks to Stuart Sierra for providing many useful ideas, discussions -;; and code contributions for lib.clj. - -(clojure/in-ns 'lib) -(clojure/refer 'clojure) - -(alias 'set 'clojure.set) - -(import '(clojure.lang RT)) -(import '(java.io BufferedReader InputStreamReader)) -(import '(java.net URI URL)) - -;; Private - -(defmacro init-once - "Initializes a var exactly once. The var must already exist." - {:private true} - [var init] - `(let [v# (resolve '~var)] - (when-not (.isBound v#) - (.bindRoot v# ~init)))) - -(def - #^{:private true :doc - "A ref to a set of symbols representing loaded libs"} - *libs*) -(init-once *libs* (ref (sorted-set))) - -(def - #^{:private true :doc - "True while a verbose load is pending"} - *verbose*) -(init-once *verbose* false) - -(def - #^{:private true :doc - "A list of keywords that clojure/refer recognizes as filters"} - *filter-keys*) -(init-once *filter-keys* '(:exclude :only :rename)) - -(def - #^{:private true :doc - "A vector of the available class loaders ordered by the degree to which - they are controlled by Clojure. The root loader's classpath can be - extended with clojure/add-classpath"} - *class-loaders* - (let [root (.ROOT_CLASSLOADER RT) - runtime (.getClassLoader (identity RT)) - system (.getSystemClassLoader ClassLoader)] - (if (= system runtime) - [root system] - [root runtime system]))) - -(defn- format - "Formats a string using String/format" - [fmt & args] - (String/format fmt (to-array args))) - -(defn- printf - "Prints formatted output" - [fmt & args] - (print (apply format fmt args))) - -(defn- throw-if - "Throws an exception with a message if pred is true. See - java.util.Formatter for format string syntax." - [pred fmt & args] - (when pred (throw (Exception. (apply format fmt args))))) - -(def find-resource) ; forward declaration -(def load-resource) ; forward declaration - -(defn- load-one - "Loads one lib from a resoure and ensures that namespace ns (if - specified) exists" - [sym url ns] - (load-resource url) - (throw-if (and ns (not (find-ns ns))) - "namespace '%s' not found after loading '%s'" ns url) - (dosync - (commute *libs* conj sym))) - -(defn- load-all - "Loads a lib from a resource and forces a load of any libs which it - directly or indirectly loads via require/use/load-libs" - [sym url ns] - (dosync - (commute *libs* set/union - (binding [*libs* (ref (sorted-set))] - (load-one sym url ns) - @*libs*)))) - -(defn sym-file - "Returns the implementation file path for a libspec sym" - [sym] - (let [n (name sym) - index (inc (.lastIndexOf n (int \.))) - leaf (.substring n index) - ns (if (zero? index) (name (ns-name *ns*)) n) - file-new (str (.replace ns \. \/) \/ leaf ".clj") - file-old (str sym ".clj")] - (if (find-resource file-new) - file-new - file-old))) - -(defn- load-lib - "Loads a lib with options: sequential keywords and arguments. The - arguments to all options are evaluated so literal symbols or lists must - be quoted" - [sym & options] - (let [raw-opts (apply hash-map options) - opts (zipmap (keys raw-opts) (map eval (vals raw-opts))) - in (:in opts) - ns (:ns opts) - reload (:reload opts) - reload-all (:reload-all opts) - require (:require opts) - use (:use opts) - verbose (:verbose opts) - loaded (contains? @*libs* sym) - load (cond reload-all - load-all - (or reload (not require) (not loaded)) - load-one) - namespace (when use (or ns sym)) - path (str (if in (str in \/)) (sym-file sym)) - url (find-resource path) - filter-opts (select-keys opts *filter-keys*)] - (binding [*verbose* (or *verbose* verbose)] - (when load - (when *verbose* - (printf "(lib/load-resource \"%s\")\n" url) - (flush)) - (throw-if (not url) "'%s' not found in classpath" path) - (load sym url namespace)) - (when namespace - (when *verbose* - (printf "(clojure/in-ns '%s)\n" (ns-name *ns*)) - (printf "(clojure/refer '%s" namespace) - (dorun (map - #(printf " %s '%s" (key %) (print-str (val %))) - filter-opts)) - (printf ")\n")) - (apply refer namespace (mapcat seq filter-opts)))))) - -;; Resources - -(defn find-resource - "Searches for a resource given a path relative to classpath using - available ClassLoaders. Returns a URL if the resource is found or nil." - [rel-path] - (some #(.findResource % rel-path) *class-loaders*)) - -(defn load-resource - "Loads Clojure source from a resource specified by an absolute path. The - path may be a URI, URL, or String. Accepts any URI scheme supported by - URLConnection (http and jar), plus file paths." - [abs-path] - (let [url (cond (instance? URL abs-path) - abs-path - (instance? URI abs-path) - (.toURL abs-path) - (string? abs-path) - (URL. abs-path))] - (throw-if (not url) "Cannot coerce %s to %s" (class abs-path) URL) - (with-open reader - (BufferedReader. - (InputStreamReader. - (.openStream url))) - (.load Compiler reader (.getPath url) (.getFile url))))) - -;; Core - -(defn load-libs - "Searches classpath for libs and loads them. 'load-libs' accepts zero or - more arguments where each argument is either a libspec that identifies a - lib to load, or a flag that modifies how all the identified libs are - loaded. - - A libspec is either a symbol or a list containing a symbol followed by - zero or more options. Since the arguments to 'load-libs' are evaluated - before the call, any literal libspecs passed in must be quoted. - - The 'require' and 'use' macros offer a simpler interface to the - capabilities of load-libs and don't evaluate the libspecs they take as - arguments. - - An option is a keyword followed by an argument. - Recognized options: :in, :ns, :exclude, :only, :rename - - All arguments to options within libspecs are evaluated so literal lists - and symbols appearing within libspecs must be quoted. - - The :in option's argument must evaluate to a string specifying the path - of the lib's parent directory relative to a location in classpath. - - The :ns options's argument must evaluate to a symbol specifying the - namespace to refer for this lib if the :use flag is present. When the - :ns option is not present the namespace defaults to the one with the - same name as the lib. - - The arguments and semantics for :exclude, :only, and :rename are those - documented for clojure/refer. - - A flag is a keyword. - Recognized flags: :require, :use, :reload, :reload-all, :verbose - - :require indicates that any identified libs that are already loaded need - not be reloaded - :use triggers referring to each lib's namespace after loading - :reload forces loading of all the identified libs even if they were - loaded previously. :reload supersedes :require - :reload-all implies :reload and also forces loading of all libs that the - identified libs directly or indirectly load via load-libs/require/use - :verbose triggers printing a message after loading each lib" - [& args] - (let [libspecs (filter (complement keyword?) args) - flags (filter keyword? args) - flag-opts (interleave flags (repeat true))] - (doseq libspec libspecs - (let [combine (if (symbol? libspec) cons concat)] - (apply load-lib (combine libspec flag-opts)))))) - -(defn libs - "Returns a sorted set of symbols naming loaded libs" - [] - @*libs*) - -;; Convenience - -(defmacro require - "Searches classpath for libs and (by default) loads them if they are not - already loaded. 'require' accepts zero or more arguments where each - argument is either a libspec that identifies a lib to load, or a flag - that modifies how the identified libs are loaded. - - A libspec is a symbol or a list containing a symbol followed by zero or - more options. 'require' does not evaluate its arguments so libspecs and - flags should not be quoted. - - An option is a keyword followed by an argument. - Recognized options: :in - - All arguments to options within libspecs are evaluated so literal lists - and symbols appearing within libspecs must be quoted. - - The :in option's argument must evaluate to a string specifying the path - of the lib's parent directory relative to a location in classpath. - - A flag is a keyword. - Recognized flags: :reload, :reload-all, :verbose - - :reload forces loading of all the identified libs even if they were - loaded previously - :reload-all implies :reload and also forces loading of all libs that the - identified libs directly or indirectly load via load-libs/require/use. - :verbose triggers printing a message after loading each lib" - [& args] - `(apply load-libs :require '~args)) - -(defmacro use - "Searches classpath for libs and (by default) loads them if they are not - already loaded and refers to namespaces with the same name. 'use' accepts - zero or more arguments where each argument is either a libspec that - identifies a lib to load, or a flag that modifies how the identified libs - are loaded. - - A libspec is a symbol or a list containing a symbol followed by zero or - more options. 'use' does not evaluate its arguments so libspecs and flags - should not be quoted. - - 'use' recognizes all the libspecs, options and flags documented for - 'require' plus some additional options in libspecs. - - Additional options: :ns, :exclude, :only, :rename - - All arguments to options within libspecs are evaluated so literal lists - and symbols appearing within libspecs must be quoted. - - The :ns options's argument must evaluate to a symbol specifying the - namespace to refer for this lib. - - The arguments and semantics for :exclude, :only, and :rename are those - documented for clojure/refer." - [& args] - `(apply load-libs :require :use '~args)) diff --git a/memoize.clj b/memoize.clj deleted file mode 100644 index ce59edb6..00000000 --- a/memoize.clj +++ /dev/null @@ -1,32 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; File: memoize.clj -;; -;; scgilardi (gmail) -;; 02 June 2008 -;; -;; Based on Common Lisp code from: -;; http://asymmetrical-view.com/talks/lisp-presentation/lisp-presentation.pdf - -(clojure/in-ns 'memoize) -(clojure/refer 'clojure) - -(defn memoize - "Returns a memoized version of a referentially transparent function. The - memoized version of the function keeps a cache of the mapping from arguments - to results and, when calls with the same arguments are repeated often, has - higher performance at the expense of higher memory use." - [function] - (let [cache (ref {})] - (fn [& args] - (or (@cache args) - (let [result (apply function args)] - (dosync - (commute cache assoc args result)) - result))))) diff --git a/ns-utils.clj b/ns-utils.clj deleted file mode 100644 index ca2395e7..00000000 --- a/ns-utils.clj +++ /dev/null @@ -1,88 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; ns-utils.clj -;; -;; Namespace Utilities -;; -;; 'ns' returns the namespace named by a symbol or throws -;; if the namespace does not exist -;; -;; 'ns-vars' returns a sorted seq of symbols naming public vars -;; in a namespace -;; -;; 'print-dir' prints a sorted directory of public vars in a -;; namespace -;; -;; 'print-docs' prints documentation for the public vars in a -;; namespace -;; -;; Convenience -;; -;; 'vars' returns a sorted seq of symbols naming public vars -;; in a namespace (macro) -;; -;; 'dir' prints a sorted directory of public vars in a -;; namespace (macro) -;; -;; 'docs' prints documentation for the public vars in a -;; namespace (macro) -;; -;; scgilardi (gmail) -;; 23 April 2008 - -(clojure/in-ns 'ns-utils) -(clojure/refer 'clojure) - -;; Namespace Utilities - -(defn ns - "Returns the namespace named by ns-sym or throws if the - namespace does not exist" - [ns-sym] - (let [ns (find-ns ns-sym)] - (when-not ns - (throw (new Exception (str "Unable to find namespace: " - ns-sym)))) - ns)) - -(defn ns-vars - "Returns a sorted seq of symbols naming public vars in - a namespace" - [ns] - (sort (map first (ns-publics ns)))) - -(defn print-dir - "Prints a sorted directory of public vars in a namespace" - [ns] - (doseq item (ns-vars ns) - (println item))) - -(defn print-docs - "Prints documentation for the public vars in a namespace" - [ns] - (doseq item (ns-vars ns) - (print-doc (ns-resolve ns item)))) - -;; Convenience - -(defmacro vars - "Returns a sorted seq of symbols naming public vars in - a namespace" - [nsname] - `(ns-vars (ns '~nsname))) - -(defmacro dir - "Prints a sorted directory of public vars in a namespace" - [nsname] - `(print-dir (ns '~nsname))) - -(defmacro docs - "Prints documentation for the public vars in a namespace" - [nsname] - `(print-docs (ns '~nsname))) diff --git a/pred.clj b/pred.clj deleted file mode 100644 index 99e2b715..00000000 --- a/pred.clj +++ /dev/null @@ -1,108 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; pred.clj -;; -;; Some clojure predicates -;; -;; scgilardi (gmail) -;; 28 June 2008 - -(clojure/in-ns 'pred) -(clojure/refer 'clojure) - -(defn coll? - "Returns true if x implements IPersistentCollection" - [x] - (instance? clojure.lang.IPersistentCollection x)) - -(defn list? - "Returns true if x implements IPersistentList" - [x] - (instance? clojure.lang.IPersistentList x)) - -;; map - -(defn set? - "Returns true if x implements IPersistentSet" - [x] - (instance? clojure.lang.IPersistentSet x)) - -(defn stack? - "Returns true if x implements IPersistentStack" - [x] - (instance? clojure.lang.IPersistentStack x)) - -;; vector - -(defn ref? - "Returns true if x implements IRef" - [x] - (instance? clojure.lang.IRef x)) - -;; seq -;; var - -(defn map-entry? - "Returns true if x is a MapEntry" - [x] - (instance? clojure.lang.MapEntry x)) - -(defn atom? - "Returns true if x is not a collection" - [x] - (not (coll? x))) - -(defn number? - "Returns true if x is a Number" - [x] - (instance? Number x)) - -(defn ratio? - "Returns true if x is a Ratio" - [x] - (instance? clojure.lang.Ratio x)) - -(defn range? - "Returns true if x is a Range" - [x] - (instance? clojure.lang.Range x)) - -(defn function? - "Returns true if x implements IFn" - [x] - (instance? clojure.lang.IFn x)) - -(defmacro macro? - "Returns true if x is a function and the symbol of the - same name can be resolved and has its :macro metadata - set" - [x] - `(and (function? ~x) (boolean (:macro ^#'~x)))) - -(defn integer? - "Returns true if x is an integer" - [x] - (or (instance? Integer x) - (instance? Long x) - (instance? BigInteger x))) - -(defn even? - "Returns true if x is even, throws an exception if x is not an integer" - [x] - (zero? (bit-and x 1))) - -(defn odd? - "Returns true if x is odd, throws an exception if x is not an integer" - [x] - (not (even? x))) - -(defn empty? - "Returns true if coll is empty" - [coll] - (not (seq coll))) diff --git a/seq-utils.clj b/seq-utils.clj deleted file mode 100644 index 7d0bb6da..00000000 --- a/seq-utils.clj +++ /dev/null @@ -1,54 +0,0 @@ -;;; seq-utils.clj -- Sequence utilities for Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 8, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -(clojure/in-ns 'seq-utils) -(clojure/refer 'clojure) - - -;; 'flatten' written by Rich Hickey, -;; see http://groups.google.com/group/clojure/msg/385098fabfcaad9b -(defn flatten - "Takes any nested combination of sequential things (lists, vectors, - etc.) and returns their contents as a single, flat sequence." - [x] - (let [s? #(instance? clojure.lang.Sequential %)] - (filter (complement s?) (tree-seq s? seq x)))) - -(defn batch - "Returns a sequence of sequences, each containing 'size' elements - from s. DEPRECATED in favor of clojure/partition, added to boot.clj - in r865." - [size s] - (when s - (lazy-cons (take size s) (batch size (drop size s))))) - -(defn separate - "Returns a vector: - [ (filter f s), (filter (complement f) s) ]" - [f s] - [(filter f s) (filter (complement f) s)]) - -(defn includes? - "Returns true if s contains something equal (with =) to x." - [x s] - (if (some (fn [y] (= y x)) s) - true false)) - -(defn indexed - "Returns a lazy sequence of [index, item] pairs, where items come - from 's' and indexes count up from zero. - - (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])" - [s] - (map vector (iterate inc 0) s)) diff --git a/sql.clj b/sql.clj deleted file mode 100644 index 52f724a1..00000000 --- a/sql.clj +++ /dev/null @@ -1,126 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; sql.clj -;; -;; A Clojure interface to sql databases via jdbc -;; -;; scgilardi (gmail) -;; 23 April 2008 - -(clojure/in-ns 'sql) -(clojure/refer 'clojure) - -(import '(java.sql DriverManager Connection PreparedStatement ResultSet)) - -(defn get-connection - "Attempts to get a connection to a database via a jdbc URL" - [subprotocol db-name] - (let [url (str "jdbc:" subprotocol ":" db-name)] - (.getConnection DriverManager url))) - -(defmacro with-connection - "Evaluates body in the context of a connection to a database. Any updates - are committed as one transaction after evaluating body or rolled back on - any uncaught exception." - [con init & body] - `(with-open ~con ~init - (try - (.setAutoCommit ~con false)) - ~@body - (.commit ~con) - (catch Exception e# - (.rollback ~con) - (throw (Exception. "transaction rolled back" e#))))) - -(defn execute-commands - "Executes a sequence of SQL commands that do not return results" - [con commands] - (with-open stmt (.createStatement con) - (doseq cmd commands - (.addBatch stmt cmd)) - (.executeBatch stmt))) - -(defn execute-prepared-statement - "Executes a prepared statement with a sequence of parameter sets" - [con sql sets] - (with-open stmt (.prepareStatement con sql) - (doseq set sets - (doseq [index value] (map vector (iterate inc 1) set) - (.setObject stmt index value)) - (.addBatch stmt )) - (.executeBatch stmt))) - -(defmacro with-query-results - "Executes a query and then evaluates body repeatedly with rec bound to - each of the generated results in turn" - [rec con sql & body] - `(with-open stmt# (.prepareStatement ~con ~sql) - (with-open rset# (.executeQuery stmt#) - (doseq ~rec (resultset-seq rset#) - ~@body)))) - -(comment - - ;; Examples - - ;; Simple tests of sql.clj using derby as a JDBC provider. - ;; - ;; Substituting a different database should only affect the definition - ;; of 'db' below (and perhaps suggest the need for more variations of - ;; get-connection). - -(clojure/in-ns 'sql-test) -(clojure/refer 'clojure) - -(lib/use sql) - -(.forName Class "org.apache.derby.jdbc.EmbeddedDriver") - -(defn db [] - (get-connection "derby" "/tmp/test-derby.db;create=true")) - -(defn db-drop [] - (with-connection con (db) - (try - (execute-commands con - ["drop table fruit"]) - (catch Exception e)))) - -(defn db-write [] - (db-drop) - (with-connection con (db) - (execute-commands con - ["create table fruit (name varchar(32), appearance varchar(32), cost int, grade real)"]) - (execute-prepared-statement con - "insert into fruit values (?, ?, ?, ?)" - [["Apple" "red" 59 87] - ["Banana" "yellow" 29 92.2] - ["Peach" "fuzzy" 139 90.0] - ["Orange" "juicy" 89 88.6]]))) - -(defn db-read [] - (with-connection con (db) - (with-query-results rec con - "select * from fruit" - (println rec)))) - -(defn db-grade-a [] - (with-connection con (db) - (with-query-results rec con - "select name, cost from fruit where grade >= 90" - (println rec)))) - -(defn db-exception [] - (with-connection con (db) - (execute-prepared-statement con - "insert into fruit (name, appearance) values (?, ?)" - [["Grape" "yummy"] - ["Pear" "bruised"]]) - (throw (Exception. "an exception")))) -) diff --git a/str-utils.clj b/str-utils.clj deleted file mode 100644 index 8c91836f..00000000 --- a/str-utils.clj +++ /dev/null @@ -1,44 +0,0 @@ -;;; str-utils.clj -- string utilities for Clojure - -;; by Stuart Sierra <mail@stuartsierra.com> -;; April 8, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -(clojure/in-ns 'str-utils) -(clojure/refer 'clojure) - -(import '(java.util.regex Pattern)) - - -(defn re-split - "Splits the string on instances of 'pattern'. Returns a sequence of - strings. Optional 'limit' argument is the maximum number of - splits. Like Perl's 'split'." - ([#^Pattern pattern string] (seq (. pattern (split string)))) - ([#^Pattern pattern string limit] (seq (. pattern (split string limit))))) - -(defn re-gsub - "Replaces all instances of 'pattern' in 'string' with - 'replacement'. Like Ruby's 'String#gsub'." - [#^Pattern regex replacement #^String string] - (.. regex (matcher string) (replaceAll replacement))) - -(defn re-sub - "Replaces the first instance of 'pattern' in 'string' with - 'replacement'. Like Ruby's 'String#sub'." - [#^Pattern regex replacement #^String string] - (.. regex (matcher string) (replaceFirst replacement))) - -(defn str-join - "Returns a string of all elements in 'sequence', separated by - 'separator'. Like Perl's 'join'." - [separator sequence] - (apply str (interpose separator sequence))) diff --git a/string.clj b/string.clj deleted file mode 100644 index ec4edf5a..00000000 --- a/string.clj +++ /dev/null @@ -1,29 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; string.clj -;; -;; String functions -;; -;; scgilardi (gmail) -;; Created: 6 July 2008 - -(clojure/in-ns 'string) -(clojure/refer 'clojure) - -;; until Clojure supports "..." arguments, calling String/format directly -;; is just ugly enough, and could be commonly used enough to warrant a -;; Clojure wrapper. -;; -;; (let [name "world"] (format "Hello, %s!" name)) ==> "Hello, world!" - -(defn format - "Returns a string using the specified format and arguments. See - java.util.Formatter for format string syntax." - [fmt & args] - (String/format fmt (to-array args))) diff --git a/test-is.clj b/test-is.clj deleted file mode 100644 index 95a0c987..00000000 --- a/test-is.clj +++ /dev/null @@ -1,211 +0,0 @@ -;;; test-is.clj: test framework for Clojure - -;; by Stuart Sierra, http://stuartsierra.com/ -;; June 5, 2008 - -;; Thanks to Chas Emerick for contributions. - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - - -;; Inspired by many Common Lisp test frameworks and clojure/test, this -;; file is a Clojure test framework. -;; -;; Define tests as :test metadata on your fns. Use the "is" macro -;; for assertions. Examples: -;; -;; (defn add2 -;; ([x] (+ x 2)) -;; {:test (fn [] (is (= (add2 3) 5)) -;; (is (= (add2 -4) -2) -;; (is (> (add2 50) 50)))}) -;; -;; You can also define tests in isolation with the "deftest" macro: -;; -;; (deftest test-new-fn -;; (is (= (new-fn) "Awesome"))) -;; -;; Run tests with (run-tests). As in any language with macros, you may -;; need to recompile functions after changing a macro definition. - - - -(clojure/in-ns 'test-is) -(clojure/refer 'clojure) - -(def - #^{:doc "PrintWriter to which test results are printed; defaults to - System.err."} - *test-out* (. System err)) - - -;;; PRIVATE - -(defmacro #^{:private true} defcounter [ref-name fn-name] - `(do (def ~(with-meta ref-name {:private true}) nil) - (defn ~fn-name [] - (when ~ref-name (sync nil (commute ~ref-name inc)))))) - -(defcounter *tests* count-test) -(defcounter *assertions* count-assertion) -(defcounter *failures* count-failure) -(defcounter *exceptions* count-exception) - -(defmacro failure [reason message] - `(throw (new java.lang.AssertionError - (str ~reason (when ~message (str "; " ~message)))))) - -(defn- assert-true [form message] - `(do (count-assertion) - (let [value# ~form] - (when-not value# - (failure (str ~(pr-str form) " was false/nil") - ~message))))) - -;; Multimethod for testing expressions, dispatches on the first symbol -;; in the expression. -(defmulti assert-expr (fn [form message] (first form))) - -;; Test for (= actual expected) expressions. -(defmethod assert-expr '= [form message] - (let [expr1 (second form) - expr2 (nth form 2)] - `(do (count-assertion) - (let [value1# ~expr1 - value2# ~expr2] - (when-not (= value1# value2#) - (failure (str ~(pr-str expr1) " is " (pr-str value1#) - " but should be " (pr-str value2#)) - ~message)))))) - -;; Test for (instance? class object) expressions. -(defmethod assert-expr 'instance? [form message] - (let [clazz (second form) - object (nth form 2)] - `(do (count-assertion) - (let [value1# ~clazz - value2# ~object] - (when-not (instance? value1# value2#) - (failure (str ~(pr-str object) " has " (class value2#) - " but should have " (pr-str value1#)) - ~message)))))) - -;; Generic expression test, just check if expression evaluates to -;; logical true. -(defmethod assert-expr :default [form message] - (assert-true form message)) - -(defn- always-fail-assert [message] - `(do (count-assertion) - (failure ~message nil))) - -(defmacro #^{:private true} with-test-counters - "Creates dynamic bindings for counting the number of tests, - assertions, failures, and exceptions. Returns the results in a - map." - [& body] - `(binding [*tests* (ref 0) - *assertions* (ref 0) - *failures* (ref 0) - *exceptions* (ref 0)] - ~@body - {:tests @*tests* - :assertions @*assertions* - :failures @*failures* - :exceptions @*exceptions*})) - -(defn- run-test-fn - "Calls the function; reports errors/exceptions." - [f name] - (try - (count-test) - (f) - (catch java.lang.AssertionError e - (count-failure) - (. *test-out* (println (str "FAIL in " name ": " - (.getMessage e))))) - (catch java.lang.Exception e - (count-exception) - (. *test-out* (println (str "EXCEPTION in " name ":"))) - (.printStackTrace e *test-out*)))) - -(defn- test-var - "Finds and calls the fn in a var's :test metadata." - [v] - (when-let f (:test (meta v)) - (run-test-fn f (str v)))) - -(defn- test-interns - "Tests all interned symbols in the namespace." - [ns] - (let [ns (if (symbol? ns) (find-ns ns) ns)] - (. *test-out* (println (str "Testing " ns))) - (dorun (map test-var (vals (ns-interns ns)))))) - - -;;; PUBLIC - -(defmacro is - "Generic assertion macro. Throws AssertionError if form evaluates - logical false. Optional message will be added to the error. - - form may be one of: - * an equality test like (= expression expected-value) - * an instance? test like (instance? class expression) - * nil, which always fails - * an arbitrary expression, fails if it returns false/nil" - ([form] `(is ~form nil)) - ([form message] - (cond - (nil? form) (always-fail-assert message) - (seq? form) (assert-expr form message) - :else (assert-true form message)))) - -(defn print-results - "Prints a summary of the results from test-ns to *test-out*." - [r] - (. *test-out* - (println (str "\nRan " (:tests r) " tests " - (:assertions r) " assertions.\n" - (:failures r) " failures, " - (:exceptions r) " exceptions."))) ) - -(defn test-ns - "Runs tests on all interned symbols in the namespaces - (symbols or namespace objects). - - Returns a map with the following keys: - :tests => number of tests run - :assertions => number of assertions checked - :failures => number of failed assertions - :exceptions => number of exceptions raised - - If no namespace is given, uses *ns*." - ([] (test-ns *ns*)) - ([& namespaces] - (with-test-counters (dorun (map test-interns namespaces))))) - -(defn run-tests - "Runs tests in the given namespaces and prints a summary of - results. - - If no namespace is given, uses *ns*." - [& namespaces] - (print-results (apply test-ns namespaces))) - -(defn run-all-tests - "Runs tests in all namespaces and prints a summary of results." - [] - (apply run-tests (all-ns))) - -(defmacro deftest - "Defs an unbound Var with body in its :test fn." - [name & body] - `(def ~(with-meta name {:test `(fn [] ~@body)}))) diff --git a/trace.clj b/trace.clj deleted file mode 100644 index 4784480d..00000000 --- a/trace.clj +++ /dev/null @@ -1,55 +0,0 @@ -;;; trace.clj -- simple call-tracing macros for Clojure - -;; by Stuart Sierra, http://stuartsierra.com/ -;; June 9, 2008 - -;; Copyright (c) 2008 Stuart Sierra. All rights reserved. The use and -;; distribution terms for this software are covered by the Common -;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php) -;; which can be found in the file CPL.TXT at the root of this -;; distribution. By using this software in any fashion, you are -;; agreeing to be bound by the terms of this license. You must not -;; remove this notice, or any other, from this software. - - -;; This file defines simple "tracing" macros to help you see what your -;; code is doing. - - -(clojure/in-ns 'trace) -(clojure/refer 'clojure) - -(def - #^{:doc "PrintStream for trace output. Defaults to System.err."} - *trace-out* (. System err)) - -(defmacro trace - "Prints value of expr to standard error and returns it. Can be - inserted anywhere without affecting surrounding code. Optional - 'name' argument can be used to identify what is being traced." - ([expr] - `(let [value# ~expr] - (. *trace-out* (println - (str "TRACE: " (pr-str value#)))) - value#)) - ([name expr] - `(let [value# ~expr] - (. *trace-out* (println - (str "TRACE " ~name ": " (pr-str value#)))) - value#))) - -(defmacro deftrace - "Use in place of defn; traces each call/return of this fn, including - arguments." - [name & definition] - `(let [f# (fn ~@definition)] - (defn ~name [& args#] - (let [id# (gensym "t")] ; identifier for this invocation - (. *trace-out* - (println (str "TRACE " id# ": " ~(str name) - " called with " (pr-str args#)))) - (let [value# (apply f# args#)] ; call original fn - (. *trace-out* - (println (str "TRACE " id# ": " ~(str name) - " returned " (pr-str value#)))) - value#))))) |