スカラトラのソースを読んだとき、次のようなコードがあることがわかりました。
_protected val _response = new DynamicVariable[HttpServletResponse](null)
protected val _request = new DynamicVariable[HttpServletRequest](null)
_
DynamicVariable
という名前の興味深いクラスがあります。このクラスのドキュメントを見ましたが、いつ、なぜ使用する必要があるのかわかりません。通常使用されるwithValue()
があります。
それを使用しない場合、それが解決した問題を解決するために、代わりにどのコードを使用する必要がありますか?
(私はscalaを初めて使用します。コードを提供できれば、それは素晴らしいことです)
DynamicVariable
は、ローンと動的スコープパターンの実装です。 DynamicVariable
のユースケースはJavaのThreadLocal
とほとんど同じです(実際のところ、DynamicVariable
はInheritableThreadLocal
舞台裏)-囲まれたスコープ内で計算を行う必要がある場合に使用されます。すべてのスレッドには、変数の値の独自のコピーがあります。
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
動的変数を作成する(したがって、要求を処理する特定のスレッドにバインドする)ことは、コード内の任意の場所でそれらを取得する最も簡単な方法です(メソッド引数を通過しないなど)。それ以外の場合は明示的に)。
これはVasilによって十分に回答されていますが、理解に役立つ可能性のある簡単な例を追加します。
Println()を使用してstdout全体に書き込むコードを使用する必要があるとします。この出力をログファイルに移動させたいのですが、ソースにアクセスできません。
println()
はConsole.println()
を使用しますConsole.println()
(幸いなことに)は に基づく a DynamicVariable[PrintStream]
デフォルトはJava.lang.System.out
Console
は、動的変数のwithOut
に転送するだけの 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
これは最小限のスニペットです。
val dyn = new DynamicVariable[String]("withoutValue")
def print=println(dyn.value)
print
dyn.withValue("withValue") {
print
}
print
出力は次のようになります。
withoutValue
withValue
withoutValue