Я хочу привязать *in*
к потоку этого чтения из строки вместо "реального" потока ввода. Как это сделать?
Как создать поток ввода, который читает из строки, а не файл или URL-адрес
Ответ 1
Отъезд with-in-str
:
http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/with-in-str
ClojureDocs имеет пример своего использования:
;; Given you have a function that will read from *in*
(defn prompt [question]
(println question)
(read-line))
user=> (prompt "How old are you?")
How old are you?
34 ; <== This is what you enter
"34" ; <== This is returned by the function
;; You can now simulate entering your age at the prompt by using with-in-str
user=> (with-in-str "34" (prompt "How old are you?"))
How old are you?
"34" ; <== The function now returns immediately
Ответ 2
Вот пример кода для того, что я закончил делать. Идея - простая функция цикла чтения/печати на сервере, которая принимает поток ввода и вывода. Моя проблема заключалась в том, как генерировать тестовые потоки для такой функции, и я думал, что функция строки будет работать. Вместо этого это то, что мне нужно:
(ns test
(:use [clojure.java.io :only [reader writer]]))
(def prompt ">")
(defn test-client [in out]
(binding [*in* (reader in)
*out* (writer out)]
(print prompt) (flush)
(loop [input (read-line)]
(when input
(println (str "OUT:" input))
(print prompt) (flush)
(if (not= input "exit\n") (recur (read-line)) )
))))
(def client-stream (java.io.PipedWriter.))
(def r (java.io.BufferedReader. (java.io.PipedReader. client-stream)))
(doto (Thread. #(do (test-client r *out*))) .start)
(.write client-stream "test\n")