Skip to content

Instantly share code, notes, and snippets.

@hugoduncan
Created April 21, 2010 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugoduncan/374112 to your computer and use it in GitHub Desktop.
Save hugoduncan/374112 to your computer and use it in GitHub Desktop.
runtime string interpolation
(defmacro capture-values
"Capture the values of the specified symbols in a symbol->value map."
[& values]
(into {} (map (fn [s] [ `'~s s]) values)))
(defn <<!
"Interpolate a string given a map of symbol->value"
[f value-map]
(apply str
(map (fn [x] (if (symbol? x)
(value-map x)
(if (seq x)
(eval (clojure.walk/prewalk-replace value-map x))
x)))
(interpolate f))))
(deftest <<!-test
(testing "runtime docstring examples"
(let [v 30.5
m {:a [1 2 3]}]
(is (= "This trial required 30.5ml of solution."
(<<! "This trial required ~{v}ml of solution."
(capture-values v))))
(is (= "This trial required 30.5ml of solution."
(<<! ((fn [] "This trial required ~{v}ml of solution."))
(capture-values v))))
(is (= "There are 30 days in November."
(<<! ((fn [] "There are ~(int v) days in November."))
(capture-values v))))
(is (= "The total for your order is $6."
(<<! ((fn [] "The total for your order is $~(->> m :a (apply +))."))
(capture-values m)))))
(is (= "The total for your order is $6."
(<<! ((fn [] "The total for your order is $~(->> m :a (apply +))."))
{'m {:a [1 2 3]}})))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment