Reputation: 11
I need the way to store some data globally in Clojure. But I can't find the way to do that. I need to load some data in runtime and put it to a global pool of objects, to manipulate with it later. This pool should be accessed inside some set of functions to set/get data from it like a some sort of small in-memory database with hash-like syntax to access.
I know that it might be bad pattern in functional programming, but I don't know other way to store dynamic set of objects to access/modify/replace it in runtime. java.util.HashMap is some sort of solution, but it couldn't be accessed with sequence functions and I miss flexibility of Clojure when I need to use this kind of collection. Lisps syntax are a great, but it's a bit stucks on purity even if developer doesn't need it in some places.
This is the way I want to work with it:
; Defined somewhere, in "engine.templates" namespace for example
(def collection (mutable-hash))
; Way to access it
(set! collection :template-1-id (slurp "/templates/template-1.tpl"))
(set! collection :template-2-id "template string")
; Use it somewhere
(defn render-template [template-id data]
(if (nil? (get collection template-id)) "" (do-something)))
; Work with it like with other collection
(defn find-template-by-type [type]
(take-while #(= type (:type %)) collection)]
Have someone a way I can use for tasks like this? Thank you
Upvotes: 1
Views: 207
Reputation: 5629
Have a look at atoms.
Your example could be adapted to something like this (untested):
; Defined somewhere, in "engine.templates" namespace for example
(def collection (atom {}))
; Way to access it
(swap! collection assoc :template-1-id (slurp "/templates/template-1.tpl"))
(swap! collection assoc :template-2-id "template string")
; Use it somewhere
(defn render-template [template-id data]
(if (nil? (get @collection template-id)) "" (do-something)))
; Work with it like with other collection
(defn find-template-by-type [type]
(take-while #(= type (:type %)) @collection)]
swap!
is how you can updated the value of an atom in a thread-safe manner. Additionally note that references to collection above have been prepended by the @ sign. That is how you get the value contained in an atom. The @ sign is short for (deref collection)
.
Upvotes: 2