This is my problem:
I need run some code every time I open a new repl, searching in Google I found that I can use the file init.clj or the user.clj (with Leiningen)
This is the code I need to run:
(set! *print-length* 103)
(println "hello")
(println *print-length*)
These are the results with both of the files:
[~/project]$ lein repl
hello <- this is the println, so the file is excecuted
103 <- this is the println of *print-length* apparently change
REPL started; server listening on localhost port 20875
user=> *print-length*
nil <- but the val of *print-length* don't change
Is there something I need to do or do I have some error?
Thanks to all!
(alter-var-root #'*print-length* (constantly 103)) in ~/user.clj works for me.
As far as I know set! doesn't work outside of a binding's dynamic scope.
lein's init.clj runs in the leiningen process, not in your project process. See https://github.com/technomancy/leiningen (search for init.clj)
Related
How can I get readline-like (or rlwrap-like) functionality from my REPL when I use the repl function from clojure.main?
The background to this is that I'm utilizing and customizing the break function from The Joy of Clojure, First Edition. I'm using it from inside the lein repl REPL. When my "breakpoint" kicks in, the readline-like functionality of Leiningen's REPL is gone, which is kind of inconvenient. My muscle memory makes me hit ↑ followed quickly by Enter. Before I can stop myself, I've got this in my terminal:
debug=> ^[[A
CompilerException java.lang.RuntimeException: Unable to resolve symbol: in this context, compiling:(/tmp/form-init13211381000659590518.clj:1:1)
And now my REPL is stuck and I have to kill the terminal or the process to get out. I'd like very much if I could either get readline working in this second-level REPL or at least prevent this common issue from derailing my debug sessions.
You should use rebel readline, a new repl for clojure developed by bhauman the same guy who brought is figwheel.
https://github.com/bhauman/rebel-readline
It has rlwrap features, syntax highlighting and multi line code editing all in the terminal.
I'm not sure the rlwrap utility would help there, because the inner REPL is held by the outer one. So the input is being controlled by Java code, not the rlwrap tool.
You are causing an exception since you input a wrong value. I remember, the clojure.main/repl function might take an additional argument to handle exceptions. Probably, you could handle it somehow and just print a string "wrong input value" instead. Take a look at the documentation for REPL.
Also, you may implement your own REPL for debugging. Long ago, I used to write some kind of it, here what I've got:
(defn repl []
(let [input (read)]
(if (= input 'q)
nil
(do
(try
(let [result (eval input)]
(println result))
(catch Exception e
(println e)))
(recur)))))
That function just prompts for a proper Clojure expression in an endless loop, evaluates it and prints the result. In case of a wrong input, it prints the error and carries on. To leave the REPL, input q.
Example:
(repl)
(+ 1 2) ;; 2
fsdf8 9_fsd ;; prints a stack trace
q ;; returns nil and exit
Try Emacs with Cider as your repl. When you (break) you'll be bumped out of the Cider repl and into the Emacs Minibuffer, where your standard emacs editing shortcuts (upon which readline is modeled) continue to apply.
(def ^:private props
(doto (java.util.Properties.)
(.put "annotators" "tokenize, ssplit, pos, lemma, parse")
(.put "parse.maxlen" (str (-> config :nlp :max-sentence-length)))
(.put "pos.maxlen" (str (-> config :nlp :max-sentence-length)))))
(def ^:private pipeline (StanfordCoreNLP. props))
(defn- annotated-doc [s]
(.process pipeline s))
(def input-text (slurp "/home/you/some.txt"))
(annotated-doc input-text)
Which then produces either a properly annotated result as expected or it produces this exception:
java.lang.NullPointerException: null
MorphaAnnotator.java:68 edu.stanford.nlp.pipeline.MorphaAnnotator.addLemma
MorphaAnnotator.java:55 edu.stanford.nlp.pipeline.MorphaAnnotator.annotate
AnnotationPipeline.java:67 edu.stanford.nlp.pipeline.AnnotationPipeline.annotate
StanfordCoreNLP.java:881 edu.stanford.nlp.pipeline.StanfordCoreNLP.annotate
StanfordCoreNLP.java:910 edu.stanford.nlp.pipeline.StanfordCoreNLP.process
(Unknown Source) sun.reflect.GeneratedMethodAccessor27.invoke
DelegatingMethodAccessorImpl.java:43
sun.reflect.DelegatingMethodAccessorImpl.invoke
Method.java:606 java.lang.reflect.Method.invoke
Reflector.java:93 clojure.lang.Reflector.invokeMatchingMethod
Reflector.java:28 clojure.lang.Reflector.invokeInstanceMethod
The text file is very vanilla. I have reduced my annotators list down to what produces the issue. I have 6 GB of memory configured for it. The text file is 3886 characters long, UTF-8 BOM formatted file. It works with partial text from this file just fine. It even works if I take the whole file as in (take 3886 input-text). So I'm stumped. Not sure what to make of it. Any suggestions?
Here is a link to the text file I was using: http://nectarineimp.com/spooky-action.txt
From my project.clj file:
:dependencies [[org.clojure/clojure "1.6.0"]
[edu.stanford.nlp/stanford-corenlp "3.3.1"]
[edu.stanford.nlp/stanford-corenlp "3.3.1" :classifier "models"]]
I agree that this is was a bug in the Annotator. I'm not sure what your configuration settings were for:
(def ^:private props
(doto (java.util.Properties.)
(.put "annotators" "tokenize, ssplit, pos, lemma, parse")
(.put "parse.maxlen" (str (-> config :nlp :max-sentence-length)))
(.put "pos.maxlen" (str (-> config :nlp :max-sentence-length)))))
But they were irrelevant in reproducing the issue. I recently upgraded a project to version 3.5.2 and your code block ran without issues (CoreNLP Version History).
Running in 3.1.1 produces your results exactly. It looks like at version 3.5.0 a Java 1.8 JVM is required.
This bug appears to be fixed in version 3.4 of CoreNLP as well, which doesn't require JVM updates.
Your question was posted a while ago, so I'm pretty sure you've already figured all this out, but for the sake of Google, I've left these comments.
When I call this small function in the clojure REPL it only prints the first hello world, not hello mars. Why is that? It's not lazy (as far as I understand) otherwise the exception wouldn't get hit, in addition SO tells me println causes a flush.
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!")
(map (fn [x] (let [_ (println "Hello, Mars")
__ (throw (Exception. "talking to many planets"))]
{ :aliens? false }
)) [1 2 3])
)
Output:
(foo nil) nil Hello, World!
Exception talking to many planets test.repl/foo/fn--6580
(form-init13300486174634970.clj:5)
First of all, map is actually lazy, so foo returns a LazySeq, which is then forced when the REPL prints it. Now when I run your example using bare Clojure (java -jar clojure.jar), I get the following output:
user=> (foo nil)
nil Hello, World!
(Hello, Mars
Exception talking to many planets user/foo/fn--1 (NO_SOURCE_FILE:5)
user=>
I get the same result with both Clojure 1.4.0 and 1.5.1.
Now if I run via lein repl, I get the output you describe. So it appears that something in the nrepl chain is affecting how things are printed. This makes sense since nrepl is designed to communicate with clients over the network. There appears to be a slight bug, however, in its handling of this case. Or perhaps it re-binds flush-on-newline to false when printing the value? Sorry, I haven't dived into the code deep enough to give a more definite answer.
Incidentally, if you wrap the function call in a println, i.e. (println (foo nil)), then you get the expected output shown above.
Okay I have an idea. Map returns a lazy seq. The repl calls println (or similar) on the map which attempts to realize it, calling .toString() (or similar). Internally when print/ln is called within a print/ln it saves the output until its finishes it own, thus an exception will mean the other bits collected (print within a print) call aren't flushed.
How does one read a single keystroke from the terminal (not Swing) in Clojure?
I have tried a few things including various versions of the JLine library, but have not gotten it working (see example below).
I will happily accept a working, Unix-only (Mac, Linux, ...) example. Ideally I'd like to know how to switch buffering off for both stdin and stdout.
Here's something close:
;; project.clj dependencies:
;; [[org.clojure/clojure "1.4.0"]
;; [jline/jline "2.8"]])
(ns slosh.core
(:import [jline.console ConsoleReader])
(:gen-class))
(defn -main []
(println "start")
(let [cr (ConsoleReader.)]
(.readCharacter cr)
(println "done")))
This prints "start" but does not respond to any input except control-C.
I'm not sure how you are running this, but if you are using lein run, you will run into problems. Try using lein trampoline run.
I would link Single character console input in java/clojure but I don't seem to have enough Internet Points to do that.
Maybe also have a look at clojure-lanterna.
I am writing a text game in Clojure. I want the player to type lines at the console, and the game to respond on a line-by-line basis.
Research showed me that (read-line) is the way one is meant to get text lines from standard input in Clojure, but it is not working for me.
I am in a fresh Leiningen project, and I have added a :main clause to the project.clj pointing to the only source file:
(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"))
using lein run yields:
Entering -main
ECHO: nil
Exiting -main
In other words, there is no opportunity to enter text at the console for (read-line) to read.
How should I get Clojure to wait for characters and newline to be entered and return the corresponding string?
(I am using GNOME Terminal 2.32.1 on Linux Mint 11, Leiningen 1.6.1.1 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VM, Clojure version 1.2.1.)
Update: If I run lein repl, I can (println (read-line)), but not when I have a -main function and run using lein run.
Try "lein trampoline run". See http://groups.google.com/group/leiningen/browse_thread/thread/a07a7f10edb77c9b for more details also from https://github.com/technomancy/leiningen:
Q: I don't have access to stdin inside my project.
A: There's a problem in the library that Leiningen uses to spawn new processes that blocks access to console input. This means that functions like read-line will not work as expected in most contexts, though the repl task necessarily includes a workaround. You can also use the trampoline task to launch your project's JVM after Leiningen's has exited rather than launching it as a subprocess.
I have had similar problems and resorted to building a jar file and then running that.
lein uberjar
java -jar project-standalone.jar
It's a bit slower, though it got me unstuck. An answer that works from the repl would
be better
Wrap your read-line calls with the macro with-read-line-support which is now in ns swank.core [since swank-clojure 1.4+ I believe]:
(use 'swank.core)
(with-read-line-support
(println "a line from Emacs:" (read-line)))
Thanks to Tavis Judd for the fix.
You can use read and use a string as input.
Not sure about the lein aspects of the problem, but definitely in emacs it is impossible to make stdin work. However, if you want to get text from the user, you can easily do it using a JOptionPane like this code from my little tic-tac-toe program:
(defn get-input []
(let [input (JOptionPane/showInputDialog "Enter your next move (row/column)")]
(map #(Integer/valueOf %) (.split input "/"))))