2011-10-10 10 views
5

Sto scrivendo un gioco di testo in Clojure. Voglio che il giocatore digiti le righe sulla console e che il gioco risponda linea per linea.Clojure (riga di lettura) non attende l'input

La ricerca mi ha mostrato che (read-line) è il modo in cui si intende ottenere righe di testo dallo standard input in Clojure, ma non funziona per me.

Sono in un progetto di Leiningen fresco, e ho aggiunto una clausola :main al project.clj che punta alla sola file sorgente:

(ns textgame.core) 

(defn -main [& args] 
    (println "Entering -main") 
; (flush)      ;makes no difference if flush are commented out 
    (let [input (read-line)] 
    (println "ECHO:" input)) 
; (flush) 
    (println "Exiting -main")) 

utilizzando lein run rendimenti:

Entering -main 
ECHO: nil 
Exiting -main 

In altre parole , non è possibile immettere testo nella console per (read-line) da leggere.

Come devo fare in modo che Clojure attenda l'inserimento di caratteri e newline e restituisca la stringa corrispondente?

(sto usando GNOME Terminal 2.32.1 su Linux Mint 11, Leiningen 1.6.1.1 su Java 1.6.0_26 di Java HotSpot (TM) a 64 bit di server VM, Clojure versione 1.2.1.)

Aggiornamento : Se eseguo lein repl, posso (println (read-line)), ma non quando ho una funzione -main ed eseguo utilizzando lein run.

+0

possibile duplicato di [Clojure (read-line) restituisce nil; non richiede] (http: // StackOverflow.it/questions/5861373/clojures-read-line-returns-nil-does-not-prompt) – amalloy

+0

@amalloy L'ipotesi migliore nella risposta a cui ci si è collegati era che si trattava di un problema con Swank-Clojure/SLIME. Non sto usando nessuno di questi. – dukereg

+1

hai provato a eseguire lo script direttamente con java -cp clojure.jar clojure.main /path/to/myscript.clj per scartare altri problemi e concentrarti sui problemi di esecuzione di lein? – jneira

risposta

1

Ho avuto problemi simili e ho fatto ricorso alla creazione di un file jar e quindi all'esecuzione di quello.

lein uberjar 
java -jar project-standalone.jar 

È un po 'più lento, anche se mi ha fatto scollare. Una risposta che funziona dal repl sarebbe essere migliore

+0

Hai ragione; questo è lento, ma funziona. Sembra che lein run abbia qualcosa di sbagliato in questo. – dukereg

+2

Le persone con lo stesso problema dovrebbero notare che hanno bisogno di (: gen-class) nella dichiarazione dello spazio dei nomi prima di eseguire il jar autonomo in questo modo. – dukereg

0

Non sono sicuro degli aspetti lein del problema, ma sicuramente in emacs è impossibile eseguire lo stdin. Tuttavia, se si desidera ottenere il testo da parte dell'utente, si può facilmente farlo utilizzando un JOptionPane come questo codice dal mio piccolo programma tic-tac-toe:

(defn get-input [] 
    (let [input (JOptionPane/showInputDialog "Enter your next move (row/column)")] 
    (map #(Integer/valueOf %) (.split input "/")))) 
6

Prova "Lein run trampolino". Vedere http://groups.google.com/group/leiningen/browse_thread/thread/a07a7f10edb77c9b per maggiori dettagli anche da https://github.com/technomancy/leiningen:

D: Non ho accesso a stdin all'interno del mio progetto.

A: C'è un problema nella libreria che Leiningen utilizza per generare nuovi processi che blocca l'accesso all'input della console. Ciò significa che funzioni come read-line non funzioneranno come previsto nella maggior parte dei contesti, sebbene l'attività repl includa necessariamente una soluzione alternativa. Puoi anche utilizzare l'attività trampolino per avviare la JVM del tuo progetto dopo che è uscito Leiningen anziché lanciarlo come sottoprocesso.

1

Avvolgere la lettura riga chiama con la macro con-lettura-line-supporto che ora è in ns swank.core [dal Swank-clojure 1.4+ Credo]:

(use 'swank.core) 
(with-read-line-support 
    (println "a line from Emacs:" (read-line))) 

Grazie a Tavis Judd per la correzione.