aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorscgilardi <scgilardi@gmail.com>2009-03-22 02:38:57 +0000
committerscgilardi <scgilardi@gmail.com>2009-03-22 02:38:57 +0000
commitb39e9fe6466b409e4b62642f0a1a49f32f00daa3 (patch)
tree12e7cd6ef9d2406c2205f001ea5d6a701980918d /src
parent5d0355f71e8b98af425d4149b009ac687cd29bd8 (diff)
issue 34: add .?. and -?> from Laurent Petit
Diffstat (limited to 'src')
-rw-r--r--src/clojure/contrib/core.clj40
-rw-r--r--src/clojure/contrib/core/tests.clj36
2 files changed, 76 insertions, 0 deletions
diff --git a/src/clojure/contrib/core.clj b/src/clojure/contrib/core.clj
new file mode 100644
index 00000000..6ce8c6e0
--- /dev/null
+++ b/src/clojure/contrib/core.clj
@@ -0,0 +1,40 @@
+; Copyright (c) Laurent Petit and others, March 2009. All rights reserved.
+
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html 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.
+
+;; functions/macros variants of the ones that can be found in clojure.core
+
+;; note to other contrib members: feel free to add to this lib
+
+(ns clojure.contrib.core
+ (:use clojure.contrib.def))
+
+(defmacro- defnilsafe [docstring non-safe-name nil-safe-name]
+ `(defmacro ~nil-safe-name ~docstring
+ {:arglists '([~'x ~'form] [~'x ~'form ~'& ~'forms])}
+ ([x# form#]
+ `(let [~'i# ~x#] (when-not (nil? ~'i#) (~'~non-safe-name ~'i# ~form#))))
+ ([x# form# & more#]
+ `(~'~nil-safe-name (~'~nil-safe-name ~x# ~form#) ~@more#))))
+
+(defnilsafe
+ "Same as clojure.core/-> but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation).
+ Examples :
+ (-?> \"foo\" .toUpperCase (.substring 1)) returns \"OO\"
+ (-?> nil .toUpperCase (.substring 1)) returns nil
+ "
+ -> -?>)
+
+(defnilsafe
+ "Same as clojure.core/.. but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation).
+ Examples :
+ (.?. \"foo\" .toUpperCase (.substring 1)) returns \"OO\"
+ (.?. nil .toUpperCase (.substring 1)) returns nil
+ "
+ .. .?.)
diff --git a/src/clojure/contrib/core/tests.clj b/src/clojure/contrib/core/tests.clj
new file mode 100644
index 00000000..ddc79dc7
--- /dev/null
+++ b/src/clojure/contrib/core/tests.clj
@@ -0,0 +1,36 @@
+; Copyright (c) Laurent Petit, March 2009. All rights reserved.
+
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file epl-v10.html 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.
+
+;; test namespace for clojure.contrib.core
+
+;; note to other contrib members: feel free to add to this lib
+
+(ns clojure.contrib.core.tests
+ (:use clojure.contrib.test-is)
+ (:use clojure.contrib.core))
+
+(deftest test-classic-versions
+ (testing "Classic -> throws NPE if passed nil"
+ (is (thrown? NullPointerException (-> nil .toString)))
+ (is (thrown? NullPointerException (-> "foo" seq next next next .toString))))
+ (testing "Classic .. throws NPE if one of the intermediate threaded values is nil"
+ (is (thrown? NullPointerException (.. nil toString)))
+ (is (thrown? NullPointerException (.. [nil] (get 0) toString)))))
+
+(deftest test-new-versions
+ (testing "Version -?> returns nil if passed nil"
+ (is (nil? (-?> nil .toString)))
+ (is (nil? (-?> "foo" seq next next next .toString))))
+ (testing "Version -?> works well for some basic use cases"
+ (is (= (list \O \O) (-?> "foo" .toUpperCase rest))))
+ (testing "Version .?. returns nil if one of the intermediate threaded values is nil"
+ (is (nil? (.?. nil toString)))
+ (is (nil? (.?. [nil] (get 0) toString)))))
+ \ No newline at end of file