46 votes

Quand utiliser scala.util.DynamicVariable?

Quand j'ai lu la source de scalatra, j'ai trouvé qu'il y avait du code comme:

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

Il existe une classe intéressante nommée DynamicVariable . J'ai regardé le doc de cette classe, mais je ne sais pas quand et pourquoi on devrait l'utiliser? Il a un withValue() qui est généralement utilisé.

Si nous ne l'utilisons pas, quel code devrions-nous utiliser à la place pour résoudre le problème résolu?

(Je suis nouveau sur Scala, si vous pouvez fournir du code, ce sera génial)

56voto

Vasil Remeniuk Points 12487

DynamicVariable est une mise en œuvre du prêt et de la dynamique de la portée des modèles. Cas d'utilisation d' DynamicVariable est à peu près similaire à l' ThreadLocal en Java (comme une question de fait, DynamicVariable utilise InheritableThreadLocal derrière la scène) - il est utilisé lorsque vous avez besoin de faire un calcul dans un champ clos, où chaque thread a son propre exemplaire de la valeur de la variable:

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

Étant donné qu' DynamicVariable utilise un héritables ThreadLocal, la valeur de la variable est passé pour le fils engendré dans le contexte:

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

DynamicVariable (et ThreadLocal) est utilisé dans Scalatra pour la même raison, il est utilisé dans de nombreux autres cadres (Ascenseur, Spring, Struts, etc.) - c'est un non-intrusive moyen de stocker et de transmettre autour de contexte(thread)-des informations spécifiques.

Rendant HttpServletResponse et HttpServletRequest des variables dynamiques (et, ainsi, la liaison à un thread spécifique que les processus de demande) est tout simplement le moyen le plus facile d'obtenir n'importe où dans le code (ne passant pas par des arguments de méthode ou de toute façon d'autre explicitement).

24voto

overthink Points 9471

C'est bien répondu par Vasil, mais je vais ajouter un autre exemple simple qui pourrait en outre aider à la compréhension.

Supposons que l'on doit utiliser un code qui utilise println() pour écrire tous sur stdout. Nous voulons que cette sortie pour aller à un fichier journal, mais nous n'avons pas accès à la source.

  • println() utilise Console.println()
  • Console.println() (heureusement) est basé sur un DynamicVariable[PrintStream] qui par défaut est java.lang.System.out
  • Console définit withOut qui transfère simplement à la dynamique de la variable withValue

Nous pouvons l'utiliser pour simplement résoudre notre problème:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X