Repeatedly asking for user input i.e. calling (read-line) hangs?

498 views
Skip to first unread message

Swaroop

unread,
Jul 2, 2012, 2:51:23 AM7/2/12
to clo...@googlegroups.com
Hi,

This might be a naive question, but calling this code causes a "hung" program for me, I would appreciate any suggestions on the right way to do it:

user=> (dotimes [n 5] (println "Input:") (read-line))
Input:
       abc
Input:
       def
# /hangs/

Regards,
Swaroop

Meikel Brandmeyer (kotarak)

unread,
Jul 2, 2012, 3:46:37 AM7/2/12
to clo...@googlegroups.com
Hi,

you wait for five lines. So you have to enter five lines. Enter three more and the "hung" will go away.

If you want to read an arbitrary number of lines and bail out depending on some decision you may use a lazy sequence.

(loop [lines (repeatedly read-line)]
  (let [line (first lines)]
    (when-not (bail-out? line)
      ...
      (recur (next lines)))))

Kind regards
Meikel

Swaroop

unread,
Jul 3, 2012, 3:33:30 AM7/3/12
to clo...@googlegroups.com

Hi Meikel,

I'm not sure I'm following your example, I ran this code (in Clojure 1.4)  - it does not echo back the input and it does not seem to work lazily i.e. also hangs:

(defn -main
  [& args]
  ;; https://groups.google.com/d/msg/clojure/kYNWcfajHhY/5FcSk3B71mwJ
  (println "Input something:")

  (loop [lines (repeatedly read-line)]
    (let [line (first lines)]
      (println "You entered:" line)
      (when (not= "q" line)
        (recur (next lines))))))


Regards,
Swaroop

Meikel Brandmeyer (kotarak)

unread,
Jul 3, 2012, 4:20:40 AM7/3/12
to clo...@googlegroups.com
Hi,

I suspect some terminal issue here. When providing a file with some lines in it, things work as expected:

user=> (with-open [in (clojure.lang.LineNumberingPushbackReader.
                        (clojure.java.io/reader "foo.txt"))]
         (binding [*in* in]
           (loop [lines (repeatedly read-line)]
             (println "You entered:" (first lines))
             (when (not= "q" (first lines))
               (recur (next lines))))))
You entered: a
You entered: b
You entered: c
You entered: q
nil

Note how 1, 2 and 3 following q are not printed and no hang is encountered.

Kind regards
Meikel

Stuart Sierra

unread,
Jul 3, 2012, 8:49:34 AM7/3/12
to clo...@googlegroups.com
Reading from STDIN is often broken by custom REPL environments that manage STDIN on their own, such as Leiningen or an IDE.

Try running from a "bare" REPL (e.g. java -cp ... clojure.main).

-S

Meikel Brandmeyer (kotarak)

unread,
Jul 3, 2012, 8:53:54 AM7/3/12
to clo...@googlegroups.com
Hi,


Am Dienstag, 3. Juli 2012 14:49:34 UTC+2 schrieb Stuart Sierra:
Reading from STDIN is often broken by custom REPL environments that manage STDIN on their own, such as Leiningen or an IDE.

Try running from a "bare" REPL (e.g. java -cp ... clojure.main).


I ran a bare repl via java -jar ..., but got the same problem. A direct read-line worked fine, but in the shown code it seemed to not recognize the newline. A ^Z gave an exception on unexpected EOF or so. This happened in PowerShell as well as cmd. I will check later today at home on a unixy machine.

Kind regards
Meikel

vxm

unread,
Jul 3, 2012, 9:34:23 AM7/3/12
to clo...@googlegroups.com
it is a bug in leiningen repl.

> lein repl
user=> (doall (repeatedly 3 read-line))
       line1
       line2
       line3
       line4
       line5
("line1" "line3" "line5")

> java -cp clojure.jar clojure.main
user=> (doall (repeatedly 3 read-line))
line1
line2
line3
("line1" "line2" "line3")

Reply all
Reply to author
Forward
0 new messages