2012-06-22 2 views
1

표준 Java 소켓과 루프를 사용하여 데이터를 읽거나 구문 분석하는 Clojure에 대해 더 자세히 알기 위해 간단한 IRC 봇을 작성하지만 nullpointer를 얻을 때 어떤 이유로 MOTD 종료 메시지 뒤에 JOIN 메시지를 보내려고합니다.(소켓 데이터를 쓰면) NullPointer 예외

은 여기 내 출력 write 이전 호출이 작동하기 때문에 나는이 이상한 찾을

/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 

(등 역 추적 포함)입니다 .. 여기

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

을 내 코드이고. 그런 다음 Clojure (및 자바) 멍청한 놈이어서, 나는 어리석은 짓을했을 것입니다.

누구나 아이디어가 있습니까?

편집 : 그것은 내가 자바 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

괄호에 대한 표준 lisp 규칙을 따르면 우연히이를 어렵게 만들 수 있습니다. 자기 자신의 줄에 괄호가 없다면 실수로 (foo bar) 대신에 (foo bar)를 쓰는 것은 거의 불가능합니다. 그렇게하면 매우 쉽게 눈에 띄고 수정할 수 있습니다. – amalloy

+0

@ amalloy 나는 괄호를 배치하는 것에 대한 답을 좋아하고 결국에는 그 흔적을 남기도록 지시 받았습니다. – octopusgrabbus

+0

@amalloy 똑똑한 사고가있다. 나는 그것을 염두에 두겠다. 감사. – gdude2002