I'm trying to find an idiomatic way to read through a text file (e.g.
a Git history log) where an object will be represented by several
lines of text, and when we find a line that starts a new entry we
create the old entry and continue. For example here's my first clumsy
attempt. Can anybody advise on how to do this in a more functional
style?

(def *line-re* #"[^\n]{1,}")

(defstruct commit :id :parent :msg)

(defn parse-log [filename]
  (let [text (slurp filename)
    lines (re-seq *line-re* text)]
    (with-local-vars
      [commits {}
      commit-id ""
      parent ""
      msg ""]
      (doseq [line lines]
        (if (.startsWith line "commit ")
          (do
            (if (not= @commit-id "")
              (do
                (var-set commits (conj @commits {...@commit-id (struct
commit @commit-id @parent @msg)}))
                (var-set msg "")
                (var-set parent nil)))
            (var-set commit-id (subs line 7))))
        (if (.startsWith line "parent ")
          (var-set parent (subs line 7)))
        (if (.startsWith line "    ")
          (var-set msg (str @msg "\n" (subs line 4)))))
      (var-set commits (assoc @commits @commit-id (struct commit
@commit-id @parent @msg)))
      @commits)))



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to