Dear Clojure Group,

I am currently reading the online book Pro 
Git<https://docs.google.com/document/d/1pms_fnr0m2xlYH_4CB3pMeWBdIBlly4CQGMWuogOntg/edit?hl=en>.
 
In chapter 7.4 <http://progit.org/book/ch7-4.html> (section “Enforcing a 
User-Based ACL System”) there is a task of reading in an access control list 
(ACL) file, such as the following

# avail/unavail | users | path
avail|nickh,pjhyett,defunkt,tpw
avail|usinclair,cdickens,ebronte|doc
avail|schacon|lib
avail|schacon|tests

and printing out a map of the form { "user1" [path 1, path 2], "user2" 
[path2, path3] ...}.

The author of the book provides a solution in Ruby, which I find relatively 
easy to follow, despite not having written any Ruby code before:

def get_acl_access_data(acl_file)
 # read in ACL data
 acl_file = File.read(acl_file).split("\n").reject { |line| line == '' }
 access = {}
 acl_file.each do |line|
   avail, users, path = line.split('|')
   next unless avail == 'avail'
   users.split(',').each do |user|
     access[user] ||= []
     access[user] << path
   end
 end
 access
end

I then tried the same in Clojure, but found my solution to be much less 
readable compared to the Ruby code:

(use '[clojure.string :only (split)])

(defn get-acl-access-data [file]
 (let [acl (split (slurp file) #"\n")]
   (apply merge-with #(into %1 %2)
             (map (fn [[avail users path]]
                         (let [users (split users #",")]
                            (reduce (fn [acc user]
                                            (when (= avail "avail")
                                              (assoc acc user [path])))
                                           {} users)))
                       (map #(split % #"\|") acl)))))

;; Output:
;; {"schacon" ["lib" "tests"], 
;;  "usinclair" ["doc"], 
;;  "cdickens" ["doc"], 
;;  "ebronte" ["doc"], 
;;  "tpw" [nil], 
;;  "defunkt" [nil], 
;;  "pjhyett" [nil], 
;; "nickh" [nil]}

Maybe it is just because I am still a beginner, but I am afraid I won’t be 
able to figure out immediately what this code is doing a few weeks from now.

However, I am sure there must be a better way of translating the Ruby 
version into Clojure. My main goal is on clarity, as I often struggle 
organizing my code in a way I would consider readable.

I therefore would be glad for any ideas of improvement. Any suggestions are 
highly welcome!

Best regards,

Stefan

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