Я пишу простой бот IRC, чтобы попытаться узнать больше о Clojure, используя стандартные сокеты Java и цикл для чтения/анализа данных, но я получаю nullpointer, когда По какой-то причине я пытаюсь отправить сообщение JOIN после сообщения конца MOTD.Исключение NullPointer при вызове (.write socket data)
Вот мой код ..
(use 'clojure.java.io
'[clojure.string :as s :only (split)])
(def sock (java.net.Socket. "iris.archivesmc.com" 6667))
(def write-stream (writer sock))
(def read-stream (reader sock))
(defn write [message]
(.write write-stream (str message "\r\n"))
(println (str "-> " message))
(.flush write-stream)
)
(defn parseMessage [buffer]
(if
(= (apply str (take-last 2 buffer)) "\r\n")
(do
(let [parts (split buffer #"\s")]
(println (s/replace buffer "\r\n" ""))
(when
(= (first parts) "PING")
;; We need to PONG to this or we'll ping out
(write (str "PONG " (second parts)))
)
(when
(= (apply str(take 1 (first parts))) ":")
;; Message with a numerical prefix
;; :server numeric our-nick message
(
(if
(= (second parts) "376")
;; MOTD end
;; Join #clojure
(write "JOIN #clojure") ;; This errors for some reason
)
)
)
)
""
)
buffer
)
)
(defn readLoop []
(loop [buffer ""]
;;(println (str "Looping.. -> " buffer))
(let [nbuf (parseMessage buffer)
nchr (.read read-stream) ]
(if-not (= nchr -1)
(recur (str nbuf (char nchr)))
)
)
)
)
(write "NICK gClojureTestBot")
(write "USER Clojure Imma Bot :Clojure Testing Bot")
(readLoop)
И вот мой вывод (с TRACEBACK и т.д.)
/usr/lib/jvm/jdk1.7.0_04/bin/java -Didea.launcher.port=7542 -Didea.launcher.bin.path=/home/gcoles/Downloads/idea-IC-117.418/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/jdk1.7.0_04/jre/lib/resources.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/javaws.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/jfr.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/jsse.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/deploy.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/management-agent.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/jce.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/charsets.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/plugin.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/rt.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/ext/sunec.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/ext/zipfs.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/ext/dnsns.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/ext/localedata.jar:/usr/lib/jvm/jdk1.7.0_04/jre/lib/ext/sunpkcs11.jar:/home/gcoles/IdeaProjects/ClojureBot/classes:/home/gcoles/clojure/clojure-1.4.0/clojure-1.4.0.jar:/home/gcoles/IdeaProjects/ClojureBot/src:/home/gcoles/IdeaProjects/ClojureBot/test:/home/gcoles/Downloads/idea-IC-117.418/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain clojure.main /home/gcoles/IdeaProjects/ClojureBot/src/main.clj
-> NICK gClojureTestBot
-> USER Clojure Imma Bot :Clojure Testing Bot
PING :5D2E1C22
-> PONG :5D2E1C22
:iris.archivesmc.com 001 gClojureTestBot :Welcome to the archivesmc.com IRC Network [email protected]
Exception in thread "main" java.lang.NullPointerException
at user$parseMessage.invoke(main.clj:35)
at user$readLoop.invoke(main.clj:49)
at user$eval10.invoke(main.clj:60)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.load(Compiler.java:6952)
at clojure.lang.Compiler.loadFile(Compiler.java:6912)
at clojure.main$load_script.invoke(main.clj:283)
at clojure.main$script_opt.invoke(main.clj:343)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:415)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Process finished with exit code 1
Я нахожу это странным, так как предыдущие вызовы write
работают. И снова, будучи Clojure (и Java) noob, я, вероятно, сделал что-то глупое.
У кого-нибудь есть идеи?
EDIT: В случае, если это имеет значение, я использую Java 7 и Clojure 1.4.0
Вы можете сделать это сложнее сделать это случайно, выполнив стандартные скобки для круглых скобок. Если ни один из парнеров никогда не выходит по своей линии, практически невозможно случайно записать ((foo bar)) вместо (foo bar), и если вы сделаете это очень заметно и легко исправить. – amalloy
@amalloy Мне нравится ваш ответ о позиционировании parens, и им сказали, чтобы они прошли в конце. – octopusgrabbus
@amalloy Умное мышление; Я буду помнить об этом. Благодарю. – gdude2002