2013-01-14 6 views
8

コマンドライン入力に基づいて、いくつかの実行時定数を設定する必要があります。これらの関数のコードは他のスレッドでも実行できるので、 "declare var and binding macro"の組み合わせは考慮していません。どのような賛否両論は、これを使用する代わりに原子を使用してvar(alter-var-rootと一緒に)を使用するのですか?私が知っているのが大好きだ、考慮すべきであるこれら二つのほかに別のオプションがある場合はそれは、実行時定数のvarとatomの比較

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

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

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

です。

また、理想的には、デフォルト値を別の場所(cli呼び出し)に設定したいので、私は原子に最初のvalを指定しないことをお勧めしました。しかし、原子を使用すると、代わりのものへ。

答えて

3

AFAIK alter-var-rootは、同期変数値の変更のみを保証し、この変更中の安全な読み取りを保証しません。一方、​​は本当に、アイデンティティの状態を原子的に変更します。あなたは初期値を提供したくない場合は

あなただけnilに設定することができます

(def dry-run (promise)) 

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

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

追記型の値が正確に約束をのために設計されているユースケースですvarとalter-var-rootを使用するだけで何が問題になりますか?あなたは、あなたが実際に労働者をキックオフする前に、あなたのスタートアップ関数で新しい値を設定します。だから、読書に競争はない。そして、値が必要な場所で@を保存することができます。

+0

あなたのヒントありがとうございます。 promiseに渡される値は、すべてのスレッド(自動バインディング搬送)で表示されるのか、それとも特別なことをする必要がありますか? – Don

+0

バインディングの搬送は、vars以外のものでは全く画像に入りません。プロミスとは、逆参照されたときに渡された値を生成するか、そのような値が到着するまでブロックするClojureオブジェクトのことです。スレッドは、グローバルハッシュマップを定義した場合よりも関連性はありません。 – amalloy

2

(def *dry-run* (atom nil)) 
+0

ご回答いただきありがとうございます。それは私が考えていたものです。 – Don

関連する問題