Permalink
Browse files

clojure.core.strint/<< now variadic

  • Loading branch information...
1 parent 11e198a commit 9f2590f2cf22c37ba66010983bf6eaf21a90084c @cemerick cemerick committed Sep 7, 2012
Showing with 39 additions and 14 deletions.
  1. +5 −3 README.md
  2. +16 −11 src/main/clojure/clojure/core/strint.clj
  3. +18 −0 src/test/clojure/clojure/core/strint_test.clj
View
@@ -2,13 +2,15 @@
Future home of fns proposed for core inclusion. Currently:
-* A set of short-circuiting "nil-safe" threading macros (e.g. `-?>`, `-?>>` and `.?.`)
+* A set of short-circuiting "nil-safe" threading macros (e.g. `-?>`, `-?>>` and
+ `.?.`)
* An implementation of `dissoc-in`
* An implementation of `seqable?`
* A string interpolation macro (`<<`), originally described
-[here](http://cemerick.com/2009/12/04/string-interpolation-in-clojure/).
+ [here](http://cemerick.com/2009/12/04/string-interpolation-in-clojure/).
-For more details, please see the project's [generated API documentation](http://clojure.github.com/core.incubator/).
+For more details, please see the project's [generated API
+documentation](http://clojure.github.com/core.incubator/).
## "Installation"
@@ -47,13 +47,13 @@
[s])))
(defmacro <<
- "Takes a single string argument and emits a str invocation that concatenates
- the string data and evaluated expressions contained within that argument.
- Evaluation is controlled using ~{} and ~() forms. The former is used for
- simple value replacement using clojure.core/str; the latter can be used to
- embed the results of arbitrary function invocation into the produced string.
+ "Accepts one or more strings; emits a `str` invocation that concatenates
+the string data and evaluated expressions contained within that argument.
+Evaluation is controlled using ~{} and ~() forms. The former is used for
+simple value replacement using clojure.core/str; the latter can be used to
+embed the results of arbitrary function invocation into the produced string.
- Examples:
+Examples:
user=> (def v 30.5)
#'user/v
user=> (<< \"This trial required ~{v}ml of solution.\")
@@ -64,8 +64,13 @@
#'user/m
user=> (<< \"The total for your order is $~(->> m :a (apply +)).\")
\"The total for your order is $6.\"
-
- Note that quotes surrounding string literals within ~() forms must be
- escaped."
- [string]
- `(str ~@(interpolate string)))
+ user=> (<< \"Just split a long interpolated string up into ~(-> m :a (get 0)), \"
+ \"~(-> m :a (get 1)), or even ~(-> m :a (get 2)) separate strings \"
+ \"if you don't want a << expression to end up being e.g. ~(* 4 (int v)) \"
+ \"columns wide.\")
+ \"Just split a long interpolated string up into 1, 2, or even 3 separate strings if you don't want a << expression to end up being e.g. 120 columns wide.\"
+
+Note that quotes surrounding string literals within ~() forms must be
+escaped."
+ [& strings]
+ `(str ~@(interpolate (apply str strings))))
@@ -38,3 +38,21 @@
(<< "There are ~(int v) days in November.")))
(is (= "The total for your order is $6."
(<< "The total for your order is $~(->> m :a (apply +))."))))))
+
+(deftest variadic-<<
+ (testing "docstring examples, split across multiple string literals"
+ (let [v 30.5
+ m {:a [1 2 3]}]
+ (is (= "This trial required 30.5ml of solution."
+ (<< "This trial required ~{" "v}ml of solution.")))
+ (is (= "There are 30 days in November."
+ (<< "There are ~(" "int " "v) days in November.")))
+ (is (= "The total for your order is $6."
+ (<< "The total " "for your order is" " $~(->> m :a (apply " "+))." "")))
+ (is (= (str "Just split a long interpolated string up into 1, 2, or even 3 "
+ "separate strings if you don't want a << expression to end up being "
+ "e.g. 120 columns wide.")
+ (<< "Just split a long interpolated string up into ~(-> m :a (get 0)), "
+ "~(-> m :a (get 1)), or even ~(-> m :a (get 2)) separate strings "
+ "if you don't want a << expression to end up being e.g. ~(* 4 (int v)) "
+ "columns wide."))))))

0 comments on commit 9f2590f

Please sign in to comment.