On Fri, Jan 6, 2012 at 3:02 PM, Jozef Wagner <[email protected]> wrote:
> Consider this contrived piece of code:
>
> (def aval (atom {:dumped false :contents "hello world"}))
>
> (defn update!
> [item]
> (when-not (:dumped item)
> (spit "a.out" (:contents item) :append true)
> (assoc item :dumped true)))
>
> How should I correctly call update! ? Each of following two calls have
> drawbacks.
>
> (swap! aval update!) ;; update! can be called more than once
>
> (let [new-val (update! aval)]
> ;; aval can be changed in between from other thread
> (reset! aval new-val))
>
> Best,
> Jozef
>
Jozef,
I think you can solve this by adding a little more info and keeping
the update function and side effects separate:
(def aval (atom { :contents "hello world" }))
(defn update-item [{:keys [dumped] :as item}]
(assoc item :dumped true :needs-dump (not dumped)))
(let [{:keys [needs-dump contents]} (swap! aval update-item)]
(if needs-dump
(spit "a.out" contents :append true)))
Whoever gets to aval first while it hasn't been dumped will see
needs-dump as true and write the file. Depending on your requirements,
if the file write fails, you'll might need to do some extra work to
put aval back in a state consistent with reality.
Hope this helps,
Dave
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en