2012-06-22 3 views
1

Я пишу простой бот 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

ответ

1

Проблема была со следующим блоком кода ..

  (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 
        ) 
       ) 
      ) 

В частности, () вокруг (if) заявление было удвоено. Слишком много скобок. Устранение лишних исправлено.

+1

Вы можете сделать это сложнее сделать это случайно, выполнив стандартные скобки для круглых скобок. Если ни один из парнеров никогда не выходит по своей линии, практически невозможно случайно записать ((foo bar)) вместо (foo bar), и если вы сделаете это очень заметно и легко исправить. – amalloy

+0

@amalloy Мне нравится ваш ответ о позиционировании parens, и им сказали, чтобы они прошли в конце. – octopusgrabbus

+0

@amalloy Умное мышление; Я буду помнить об этом. Благодарю. – gdude2002

Смежные вопросы