1

Clojure についてもっと学ぼうとする単純な IRC ボットを作成しています。標準の Java ソケットとループを使用してデータを読み取り/解析していますが、MOTD 終了メッセージの後に JOIN メッセージを送信しようとすると nullpointer が返されます。理由。

これが私のコードです..

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

そして、これが私の出力です(トレースバックなどを使用)

/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 gClojureTestBot!~Clojure@213.190.134.190
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) 初心者である私は、おそらくばかげたことをしたのでしょう。

誰でもアイデアはありますか?

編集:重要な場合、私はJava 7とClojure 1.4.0を使用しています

4

1 に答える 1

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)ブラケットが多すぎます。余分なものを削除すると、問題が解決しました。

于 2012-06-22T11:05:55.020 に答える