[#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, "allPublicFields": true,
"allPublicConstructors": true "allPublicConstructors": true
}, },
{
"name":"clojure.lang.LineNumberingPushbackReader",
"allPublicMethods":true,
"allPublicFields": true,
"allPublicConstructors": true
},
{ {
"name":"java.util.concurrent.LinkedBlockingQueue", "name":"java.util.concurrent.LinkedBlockingQueue",
"allPublicMethods":true "allPublicMethods":true
@ -87,8 +93,19 @@
"allPublicMethods":true, "allPublicMethods":true,
"allPublicFields": true, "allPublicFields": true,
"allPublicConstructors": 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", "name":"java.lang.System",
"allPublicMethods":true, "allPublicMethods":true,

2
sci

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

View file

@ -32,9 +32,39 @@
`(when-not ~x `(when-not ~x
(throw (~'__assertion-error__ (str "Assert failed: " ~message "\n" (pr-str '~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 (def core-extras
{'*in* *in* {'*in* #'*in*
'*out* *out* '*out* #'*out*
'binding (with-meta binding* {:sci/macro true})
'file-seq file-seq 'file-seq file-seq
'future-call future-call 'future-call future-call
'future (with-meta future {:sci/macro true}) 'future (with-meta future {:sci/macro true})
@ -56,9 +86,13 @@
'print print 'print print
'println println 'println println
'println-str println-str 'println-str println-str
'pop-thread-bindings pop-thread-bindings
'push-thread-bindings push-thread-bindings
'flush flush 'flush flush
'read-line read-line 'read-line read-line
'__close!__ __close!__ '__close!__ __close!__
'with-open (with-meta with-open* {:sci/macro true}) '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__ '__assertion-error__ __assertion-error__
'assert (with-meta assert* {:sci/macro true})}) '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 'clojure.lang.ExceptionInfo clojure.lang.ExceptionInfo
'java.lang.Integer Integer 'java.lang.Integer Integer
'java.io.File java.io.File 'java.io.File java.io.File
'clojure.lang.LineNumberingPushbackReader clojure.lang.LineNumberingPushbackReader
'java.util.regex.Pattern java.util.regex.Pattern 'java.util.regex.Pattern java.util.regex.Pattern
'java.lang.String String 'java.lang.String String
'java.io.StringReader java.io.StringReader
'java.io.StringWriter java.io.StringWriter
'java.lang.System System 'java.lang.System System
'java.lang.Thread Thread} 'java.lang.Thread Thread}
:imports '{ArithmeticException java.lang.ArithmeticException :imports '{ArithmeticException java.lang.ArithmeticException

View file

@ -257,3 +257,15 @@
nil)" nil)"
path)) path))
(is (= "foobar\nbarfoo\n" (slurp 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)))"))))