2013-01-14 6 views
8

In base all'ingresso della riga di comando, ho bisogno di impostare alcune costanti di runtime che un certo numero di funzioni downstream useranno. Il codice in queste funzioni può essere eseguito in altri thread, quindi non sto considerando la combinazione "declare var e use binding macro". Quali sono i pro/contro dell'uso di una var (con alter-var-root) per questo contro l'utilizzo di un atomo? Cioè,var contro atom per le costanti di runtime

(declare *dry-run*) ; one of my constants 

(defn -main [& args] 
    ; fetch command line option 
    ;(cli args ...) 
    (alter-var-root #'*dry-run* (constantly ...)) 
    (do-stuff-in-thread-pool)) 

contro

(def *dry-run* (atom true)) 

(defn -main [& args] 
    ; fetch command line option 
    ;(cli args ...) 
    (reset! *dry-run* ...) 
    (do-stuff-in-thread-pool)) 

Se c'è un'altra opzione oltre a questi due che dovrei prendere in considerazione, mi piacerebbe sapere.

Inoltre, preferibilmente avrei preferito non fornire una val iniziale all'atomo perché voglio settare i valori di default altrove (con l'invocazione cli), ma posso conviverci, specialmente se usare l'atomo offre vantaggi rispetto alla (e) alternativa (i).

risposta

3

AFAIK alter-var-root garantisce solo la variazione del valore di variabile sincronizzata e non garantisce la lettura sicura durante questa modifica. D'altra parte il atom fornisce davvero modificare atomicamente lo stato di identità.

Se non si desidera fornire un valore iniziale si può solo impostare per nil:

(def *dry-run* (atom nil)) 
6

valori write-once sono esattamente il caso d'uso promesse sono progettati per:

(def dry-run (promise)) 

(defn -main [] 
    (deliver dry-run true)) 

(defn whatever [f] 
    (if @dry-run 
    ...)) 
+0

Grazie per il tuo suggerimento. Il valore consegnato alla promessa sarà visibile in tutti i thread (trasferimento automatico del legame) o devo fare qualcosa di speciale per questo? – Don

+0

Il convogliamento obbligatorio non immette affatto l'immagine per niente tranne che vars. Una promessa è solo un oggetto Clojure che, quando dereferenziato, produrrà il valore che gli è stato consegnato, o bloccherà fino a quando non arriva un tale valore. I thread non sono più rilevanti di quanto sarebbero se si definisse una mappa hash globale. – amalloy

2

Cosa c'è di sbagliato con solo usando una var e alter-var-root? Si imposta il nuovo valore nella funzione di avvio, prima di dare il via ai lavoratori. Quindi non c'è razza nella lettura. E puoi salvare lo @ ovunque tu abbia bisogno del valore.

+0

Grazie per la risposta. Questo è quello che stavo pensando .. – Don

Problemi correlati