2011-02-25 26 views
42

Cuando leí la fuente de scalatra, encontré que hay algo de código como:¿Cuándo deberíamos usar scala.util.DynamicVariable?

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

Hay una clase interesante llamado DynamicVariable. He visto el documento de esta clase, pero no sé cuándo ni por qué deberíamos usarlo. Tiene un withValue() que generalmente se usa.

Si no lo usamos, ¿qué código deberíamos usar para resolver el problema?

(soy nuevo en Scala, si usted puede proporcionar algo de código, que hacerse grande)

+0

http: //scala-programming-language.1934581.n4.nabble.com/scala-Thread-Local-context-made-easy-with-Scala-td1997909.html –

Respuesta

50

DynamicVariable es una implementación del préstamo y los patrones de alcance dinámico. Use-case of DynamicVariable es bastante similar a ThreadLocal en Java (de hecho, DynamicVariable usa InheritableThreadLocal detrás de escena) - se usa cuando se necesita hacer un cálculo dentro de un alcance cerrado, donde cada hilo tiene su propia copia del valor de la variable:

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

Dado que DynamicVariable utiliza un heredable ThreadLocal, valor de la variable se pasa a las roscas dio lugar en el contexto:

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

DynamicVariable (y ThreadLocal) es utilizado en Scalatra por la misma razón que se utiliza en muchos otros marcos (Lift, Spring, Struts, etc.): es una forma no intrusiva de almacenar y transmitir información específica del contexto (hilo).

Haciendo HttpServletResponse y HttpServletRequest variables dinámicas (y, por lo tanto, la unión a un hilo específico que procesa petición) es sólo la forma más fácil de obtener en cualquier lugar en el código (que no pasa por los argumentos del método o en cualquier caso otra cosa explícitamente).

22

Esto es bien respondido por Vasil, pero agregaré un ejemplo simple adicional que podría ayudar a comprender mejor.

Supongamos que debemos usar algún código que use println() para escribir todo sobre stdout. Queremos que esta salida vaya a un archivo de registro, pero no tenemos acceso a la fuente.

  • println() utiliza Console.println()
  • Console.println() (afortunadamente) es based on un DynamicVariable[PrintStream] que por defecto es java.lang.System.out
  • Console define withOut que simplemente remite a la variable dinámica withValue

Podemos usar esto para simplemente arregle nuestro problema:

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 
13

Este es un fragmento mínimo:

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

La salida será:

withoutValue 
withValue 
withoutValue 
Cuestiones relacionadas