46

スカラトラのソースを読んだとき、次のようなコードがあることがわかりました。

protected val _response   = new DynamicVariable[HttpServletResponse](null)
protected val _request    = new DynamicVariable[HttpServletRequest](null)

という名前の興味深いクラスがありDynamicVariableます。このクラスのドキュメントを見ましたが、いつ、なぜそれを使用すべきかわかりません。withValue()通常使用されるものがあります。

それを使用しない場合、それが解決した問題を解決するために、代わりにどのコードを使用する必要がありますか?

(私はscalaを初めて使用します。コードを提供できれば、それは素晴らしいことです)

4

3 に答える 3

56

DynamicVariableローンと動的スコープパターンの実装です。のユースケースはJavaのユースケースDynamicVariableと非常によく似てThreadLocalいます(実際にDynamicVariableInheritableThreadLocal、舞台裏で使用されます)-囲まれたスコープ内で計算を行う必要がある場合に使用され、すべてのスレッドが変数の値の独自のコピーを持っています:

dynamicVariable.withValue(value){ valueInContext =>
  // value used in the context
} 

DynamicVariable継承可能なを使用するThreadLocal場合、変数の値はコンテキストで生成されたスレッドに渡されます。

dynamicVariable.withValue(value){ valueInContext =>
  spawn{
    // value is passed to the spawned thread
  }
}

DynamicVariable(およびThreadLocal)は、他の多くのフレームワーク(Lift、Spring、Strutsなど)で使用されているのと同じ理由でScalatraで使用されています。これは、コンテキスト(スレッド)固有の情報を格納および渡すための邪魔にならない方法です。

動的変数HttpServletResponseの作成HttpServletRequest(したがって、要求を処理する特定のスレッドへのバインド)は、コード内の任意の場所で変数を取得する最も簡単な方法です(メソッド引数やその他の方法で明示的に渡すことはありません)。

于 2011-02-25T12:22:14.150 に答える
24

これはVasilによって十分に回答されていますが、理解に役立つ可能性のある簡単な例を追加します。

println()を使用してstdout全体に書き込むコードを使用する必要があるとします。この出力をログファイルに移動させたいのですが、ソースにアクセスできません。

  • println()使用Console.println()
  • Console.println()(幸いなことDynamicVariable[PrintStream])デフォルトでjava.lang.System.out
  • ConsolewithOut動的変数に転送することを定義しますwithValue

これを使用して、問題を簡単に修正できます。

def noisy() { println("robot human robot human") }
noisy() // prints to stdout
val ps = new java.io.PrintStream("/tmp/mylog")
scala.Console.withOut(ps) { noisy() } // output now goes to /tmp/mylog file
于 2013-03-18T14:48:09.217 に答える
18

これは最小限のスニペットです:

val dyn = new DynamicVariable[String]("withoutValue")
def print=println(dyn.value)
print
dyn.withValue("withValue") {
  print
}
print

出力は次のようになります。

withoutValue
withValue
withoutValue
于 2015-05-11T10:12:22.297 に答える