[#112] Add binding, with-out-str and with-in-str

This commit is contained in:
Michiel Borkent 2019-11-16 23:11:42 +01:00 committed by GitHub
parent 2dfb55d4a3
commit cfb1f45e8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 5 deletions

View file

@ -64,6 +64,12 @@
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name":"clojure.lang.LineNumberingPushbackReader",
"allPublicMethods":true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name":"java.util.concurrent.LinkedBlockingQueue",
"allPublicMethods":true
@ -87,8 +93,19 @@
"allPublicMethods":true,
"allPublicFields": true,
"allPublicConstructors": true
}
,
},
{
"name":"java.io.StringReader",
"allPublicMethods":true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name":"java.io.StringWriter",
"allPublicMethods":true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name":"java.lang.System",
"allPublicMethods":true,

2
sci

@ -1 +1 @@
Subproject commit ad83ca84f8a9e6baf220b4757cde0f17b1558d6b
Subproject commit 8e4b8ff55b5afbd330a278d835fbb6fe0858df99

View file

@ -32,9 +32,39 @@
`(when-not ~x
(throw (~'__assertion-error__ (str "Assert failed: " ~message "\n" (pr-str '~x)))))))
(defn binding*
"This macro only works with symbols that evaluate to vars themselves. See `*in*` and `*out*` below."
[_ _ bindings & body]
`(do
(let []
(push-thread-bindings (hash-map ~@bindings))
(try
~@body
(finally
(pop-thread-bindings))))))
;; this works now!
"(def w (java.io.StringWriter.)) (push-thread-bindings {clojure.core/*out* w}) (try (println \"hello\") (finally (pop-thread-bindings))) (prn \">\" (str w))"
;; this also works now! "(def w (java.io.StringWriter.)) (binding [clojure.core/*out* w] (println \"hello\")) (str w)"
(defn with-out-str*
[_ _ & body]
`(let [s# (java.io.StringWriter.)]
(binding [*out* s#]
~@body
(str s#))))
(defn with-in-str*
[_ _ s & body]
`(with-open [s# (-> (java.io.StringReader. ~s) clojure.lang.LineNumberingPushbackReader.)]
(binding [*in* s#]
~@body)))
(def core-extras
{'*in* *in*
'*out* *out*
{'*in* #'*in*
'*out* #'*out*
'binding (with-meta binding* {:sci/macro true})
'file-seq file-seq
'future-call future-call
'future (with-meta future {:sci/macro true})
@ -56,9 +86,13 @@
'print print
'println println
'println-str println-str
'pop-thread-bindings pop-thread-bindings
'push-thread-bindings push-thread-bindings
'flush flush
'read-line read-line
'__close!__ __close!__
'with-open (with-meta with-open* {:sci/macro true})
'with-out-str (with-meta with-out-str* {:sci/macro true})
'with-in-str (with-meta with-in-str* {:sci/macro true})
'__assertion-error__ __assertion-error__
'assert (with-meta assert* {:sci/macro true})})

View file

@ -223,8 +223,11 @@ Everything after that is bound to *command-line-args*."))
'clojure.lang.ExceptionInfo clojure.lang.ExceptionInfo
'java.lang.Integer Integer
'java.io.File java.io.File
'clojure.lang.LineNumberingPushbackReader clojure.lang.LineNumberingPushbackReader
'java.util.regex.Pattern java.util.regex.Pattern
'java.lang.String String
'java.io.StringReader java.io.StringReader
'java.io.StringWriter java.io.StringWriter
'java.lang.System System
'java.lang.Thread Thread}
:imports '{ArithmeticException java.lang.ArithmeticException

View file

@ -257,3 +257,15 @@
nil)"
path))
(is (= "foobar\nbarfoo\n" (slurp path)))))
(deftest binding-test
(is (= 6 (bb nil "(def w (java.io.StringWriter.))
(binding [clojure.core/*out* w]
(println \"hello\"))
(count (str w))"))))
(deftest with-out-str-test
(is (= 6 (bb nil "(count (with-out-str (println \"hello\")))"))))
(deftest with-in-str-test
(is (= 5 (bb nil "(count (with-in-str \"hello\" (read-line)))"))))