2012-03-24 3 views
1

(Das folgende war ursprünglich eine Hausaufgabe, aber ich versuche es in einer neuen Sprache.)Wie kann ich die Lesezeile faul bewerten, um Eingaben zu sammeln?

In einem kurzen Clojure-Programm, ich versuche, eine Lazy-Sequenz von Eingaben (von der Befehlszeile) und von zu generieren Sie berechnen drei Zeichenwerte. Ich würde davon ausgehen, dass, möglicherweise je nachdem, wie Clojure wählte meine let Bindungen zu bewerten, dies sollte eine schnelle Serie wie folgt erzeugen:

$ clj lazy-prompts.clj 
Enter value #1: 32 
Enter value #3: 162 
Enter value #2: 12 
Enter value #4: 118 
a A 5 

Stattdessen beginnt das Programm und hängt unendlich ohne Anweisungen. Ich versuchte eifrig, den for Ausdruck durch Einwickeln in dorun auszuwerten, aber das änderte das Ergebnis nicht.

Warum erzeugt das folgende Programm keine Eingabeaufforderungen?

(use '[clojure.java.io :only (reader)]) 

(def of-input 
    (for [value-number [1 2 3 4]] 
     (dorun 
      (print (str "Enter encrypted value #" value-number)) 
      (read-line) 
     ))) 

(let [value-1 (nth of-input 1) 
     value-2 (nth of-input 2) 
     value-3 (nth of-input 3) 
     value-4 (nth of-input 4)] 

    (let [a (/ (+ value-1 value-3) 2) 
      b (/ (+ value-2 value-4) 2) 
      c (- value-4 b)] 

     (println (char a) (char b) (char c)))) 

Antwort

1

Zuerst sollten Sie Dorun durch Do ersetzen. Ersteres erwartet ein Seq als erstes oder zweites Argument und zwingt es.

Nach dieser Änderung läuft der Code mehr oder weniger korrekt. Was Sie als "hängend" wahrnehmen, wartet tatsächlich auf Ihre Eingabe. Eines der Probleme ist, dass Sie die Eingabeaufforderungen (noch) nicht sehen. Sie zeigen das tatsächlich, aber erst nachdem Sie vier Werte eingegeben haben. Wie reparierst du das? Ich weiß nicht, ich dachte immer, dass Nebenwirkungen in einer trägen Sequenz eine schlechte Idee sind, also mache ich das nie.

Das andere Problem ist, dass Read-Line-Strings zurückgibt und Sie sie als Zahlen verwenden. Sie müssen sie zuerst konvertieren.

P.S. "for" in clojure ist keine For-Schleife, es ist ein Listenverständnis.

1

print spült die Ausgabe nicht, sodass die Eingabeaufforderungen nicht sofort angezeigt werden. Verwenden Sie entweder println oder rufen Sie flush explizit wie folgt an:

(def of-input 
(for [value-number [1 2 3 4]] 
    (dorun 
     (print (str "Enter encrypted value #" value-number)) 
     (flush) 
     (read-line) 
    ))) 
Verwandte Themen