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