0

I'm writing a function to parse out IRC RFC2813 messages into their constituent parts. This consists of two functions, one to split the message via regex, and another to modify the return to handle certain special cases.

(let [test-privmsg ":[email protected] PRIVMSG #mychannel :Hiya, buddy."])

(defn ircMessageToMap [arg]
  "Convert an IRC message to a map based on a regex"
  (println (str "IRCMapifying " arg))
  (zipmap [:raw :prefix :type :destination :message]
          (re-matches #"^(?:[:](\S+) )?(\S+)(?: (?!:)(.+?))?(?: [:](.+))?$"
                      arg
                      )
          )
  )

(defn stringToIRCMessage [arg]
   "Parses a string as an IRC protocol message, returning a map"
     (let [r (doall (ircMesgToMap arg))])
     (println (str "Back from the wizard with " r))
     (cond
       ;Reformat PING messages to work around regex shortcomings
       (= (get r :prefix) "PING") (do
                                    (assoc r :type (get r :prefix))
                                    (assoc r :prefix nil)
                                  )
       ;Other special cases here
       :else r)
  )

The problem I'm running into is that the stringToIRCMessage function doesn't appear to be realizing the return value of ircMesgToMap. If I evaluate (stringToIRCMessage test-privmsg), the println statement gives me:

Back from the wizard with Unbound: #'irc1.core/r

..but the "IRCMapifying" result from ircMessageToMap appears on the console beforehand indicating that it was evaluated correctly.

The doall was an attempt to force the result to be realized in the middle of the function - it had no effect.

How should I rewrite this stringToIRCMessage function to get the r variable usable?

1
  • 1
    You will also have to fix your (do (assoc ...) (assoc ...)), since the first of these has no effect. Remember that Clojure values are immutable, and that (g (f x)) is very different from (do (f x) (g x)). Commented Aug 21, 2017 at 21:51

1 Answer 1

2

The parens are wrong in your let statement.

Should look like this:

  (let [r (doall (ircMesgToMap arg)) ]
     (println (str "Back from the wizard with " r))
     (cond
       ;Reformat PING messages to work around regex shortcomings
       (= (get r :prefix) "PING") (do
                                    (assoc r :type (get r :prefix))
                                    (assoc r :prefix nil)
                                  )
       ;Other special cases here
       :else r))
Sign up to request clarification or add additional context in comments.

3 Comments

I need to have the entire rest of the function under the let block?
Only the part that cares about the value r. It is "lexically scoped" just like in Java, C, etc (i.e. it is a "local variable" that doesn't exist, i.e. is "unbound", outside of the block)
Aha. I was under the assumption that the form by itself in the function bound it to the scope of the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.