<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Duchess France &#187; PSUG</title>
	<atom:link href="http://jduchess.org/duchess-france/blog/tag/psug/feed/" rel="self" type="application/rss+xml" />
	<link>http://jduchess.org/duchess-france</link>
	<description>A Duchess Community Blog for France</description>
	<lastBuildDate>Wed, 18 Jan 2012 14:02:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>PSUG#1 La première du Scala User Group</title>
		<link>http://jduchess.org/duchess-france/blog/psug1-la-premiere-du-scala-user-group/</link>
		<comments>http://jduchess.org/duchess-france/blog/psug1-la-premiere-du-scala-user-group/#comments</comments>
		<pubDate>Mon, 24 May 2010 15:15:52 +0000</pubDate>
		<dc:creator>Claude Falguière</dc:creator>
				<category><![CDATA[Les Conférences]]></category>
		<category><![CDATA[PSUG]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Simple Build Tool]]></category>

		<guid isPermaLink="false">http://jduchess.org/duchess-france/?p=580</guid>
		<description><![CDATA[Le Paris Scala User Group a fait sa première réunion le 18 mai.  50 personnes étaient inscrites et une bonne quarantaine étaient présentes parmi lesquelles quelques personnalités (Nicolas Martignole, Emmanuel Bernard, Sébastien Douche, Romain Maton par exemple). J&#8217;ai dignement représenté Duchess France dans cette première et j&#8217;espère que vous viendrez nombreuses (bon allez, nombreux aussi [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-588" style="margin-bottom:5px;margin-right:5px" title="LogoScala" src="http://jduchess.org/duchess-france/files/2010/05/LogoScala.png" alt="LogoScala" width="63" height="87" />Le Paris Scala User Group a fait sa première réunion le 18 mai.  50 personnes étaient inscrites et une bonne quarantaine étaient présentes parmi lesquelles quelques personnalités (Nicolas Martignole, Emmanuel Bernard, Sébastien Douche, Romain Maton par exemple). J&#8217;ai dignement représenté Duchess France dans cette première et j&#8217;espère que vous viendrez nombreuses (bon allez, nombreux aussi pour nos lecteurs) pour les suivantes.</p>
<p>Merci à Benoît Dissert pour m&#8217;avoir transmis ses notes que j&#8217;ai partiellement utilisées et à Alexi Agahi pour ses photos. Je remercie également les personnes qui ont posté des liens où des informations complémentaires sur la mailing list su PSUG.</p>
<p><em><span style="color: #993300">Comme je connais très peu Scala, vous pouvez  lire cet article même si vous êtes débutants. Alexandre et les autres experts Scala n&#8217;hésitez pas à corriger ce qui serait faux.</span></em></p>
<div style="margin-top:50px;margin-bottom:25px">
<h2>Présentation du Groupe</h2>
</div>
<p><a href="http://jduchess.org/duchess-france/files/2010/05/PSUG-mai-1.jpg"><img class="alignright size-full wp-image-630" style="margin-left:10px" title="PSUG-mai-1" src="http://jduchess.org/duchess-france/files/2010/05/PSUG-mai-1.jpg" alt="PSUG-mai-1" width="500" height="281" /></a>Le Paris Scala User Group a été créé par Alexis Agahi et Alexandre Bertails. Alexandre est bien connu par ici puisqu&#8217;il a déjà fait une <a href="http://jduchess.org/duchess-france/paris-jug-de-mai-build-share-deploy-jusquau-bout-de-la-nuit-1/" target="_blank">présentation du W3C au JUG</a> en mai.</p>
<p>Si vous êtes motivés pour vous investir dans une communauté, ce groupe cherche des volontaires.</p>
<p>Le Paris Scala User Group a une communauté Google Group sous le nom <a href="http://groups.google.com/group/paris-scala-user-group" target="_blank">paris-scala-user-group</a>. Il a à ce jour 85 membres et je vous recommande de rejoindre ce groupe si Scala vous intéresse.</p>
<p>Pour cette première, <a href="http://www.xebia.fr/" target="_blank">Xebia </a>a prêté une salle de 50 places dans ses locaux et nous a offert une collation. </p>
<div style="margin-top:50px;margin-bottom:25px">
<h2>Le sujet du jour</h2>
</div>
<p>Alexandre a voulu nous faire part de son retour d&#8217;expérience sur les projets qu&#8217;il réalise en Scala au <a href="http://www.w3.org/">W3C</a>. Plusieurs projets de son équipe sont faits en Scala ou en Lift, en particulier le nouveau <a href="http://jigsaw.w3.org/css-validator/" target="_blank">validateur CSS</a>.</p>
<p>Le thème qu&#8217;il a choisi aujourd&#8217;hui est l&#8217;injection de dépendance en Scala. Comme il a un tout petit peu oublié de présenter le thème avant de rentrer dans le vif du sujet il a fait une présentation après coup et je reprend donc simplement l&#8217;&#8221;introduction&#8221; qu&#8217;il a fait sur la mailing list.</p>
<div style="margin-left:30px;margin-right:30px;padding-left:10px;padding-right:20px;padding-top:5px;padding-bottom:5px;background-color:#eeeeee">
<ul>
<li><em>le premier message était au sujet des frameworks Java. Déjà, ils fonctionnent en Scala. Mais il faut comprendre les problèmes que ça amène, en particulier le fait que ça peut introduire beaucoup d&#8217;erreurs car on tombe en dehors du système de type. De plus, ils sont trop intrusifs : soient ils apparaissent dans le code (annotations), soit il faut utiliser des setters (Spring/XML)&#8230; En tout cas, on ne visualise pas les dépendances dans le code métier.</em></li>
<li><em>j&#8217;ai donc cherché à montrer comment les traits de langage de Scala, avec un peu de réflexion, peuvent être utilisés pour arriver à la même chose. Le but est de ne pas sacrifier le typage, de pouvoir se reposer sur la phase de check du compilateur et d&#8217;exprimer les dépendances par des types et non la documentation.</em></li>
<li><em> la profusion des méthodes montrait qu&#8217;il n&#8217;y a pas aujourd&#8217;hui de solution vraiment satisfaisante, ce que je n&#8217;ai jamais cherché à cacher, puisque je cherche encore pour mes besoins personnels une solution &#8220;opérationnelle&#8221; et élégante en terme de modélisation. Par exemple : garder la sémantique introduite par les self-reference pour parler des environnements/dépendances à injecter.</em></li>
</ul>
</div>
<p>Pour ses examples de code, il s&#8217;est inspiré du code Scala d&#8217;un outil d&#8217;interface à leur DVCS (et oui on boucle un peu en ce moment, voir aussi <a href="http://jduchess.org/duchess-france/paris-jug-de-mai-build-share-deploy-jusquau-bout-de-la-nuit-2/" target="_blank">les DVCS</a> au JUG).   Même si leur choix s&#8217;est porté sur <em> </em>Mercurial, le code ne dépend pas d&#8217;un DVCS en particulier &#8230;  jusqu&#8217;au moment où il faut tester.</p>
<p>L&#8217;exemple que nous avons étudié avec Alexandre  montre comment injecter les instances du DVCS et de l&#8217;environnement requis au moment du test soit en utilisation seulement les capacités de Scala et différents patterns, soit en utilisant <a href="http://code.google.com/p/google-guice/" target="_blank">Guice </a>comme framework d&#8217;injection de dépendance.</p>
<div style="margin-top:50px;margin-bottom:25px">
<h2>L&#8217;environnement de développement et les outils</h2>
</div>
<p>La session a été l&#8217;occasion de discussion intéressantes sur les outils.</p>
<p>Alexandre a écrit un <a href="http://www.bertails.org/blog/scala_sbt_emacs" target="_blank">tutorial </a>sur l&#8217;installation sous Linux d&#8217;un environnement de développement <a href="http://www.scala-lang.org/" target="_blank">Scala</a> basé sur <a href="http://code.google.com/p/simple-build-tool/" target="_blank">SBT</a> (Simple Build Tool) et <a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a> (ou vi).</p>
<p><em>Si vous n&#8217;êtes pas sous Linux, il faudra un peut vous débrouiller mais a priori tout ça  fonctionne aussi avec les versions portées. Il y a quelques billets de Xebia qui traitent aussi de l&#8217;installation d&#8217;environnement pour Scala</em></p>
<p>Comme il y avait beaucoup à dire sur les éditeurs de texte et SBT,  ils ont une section à part.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Scala</h3>
</div>
<p>S&#8217;il faut vous rafraichir un peu la mémoire sur Scala, vous pouvez vous reporter aux <a href="http://jduchess.org/duchess-france/paris-jug-retour-sur-la-soiree-scala/" target="_blank">présentations du JUG</a> en avril. Le tutorial cité ci-dessus vous aidera à installer Scala.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>ScalaTest</h3>
</div>
<p><a href="http://www.scalatest.org/" target="_blank">ScalaTest </a>permet d&#8217;écrire les tests unitaires pour Scala.</p>
<p>Un test très basique pour vérifier que l&#8217;environnement fonctionne.</p>
<div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border: solid thin;border-color: grey"><code>import org.scalatest.FunSuite</p>
<p>class Test extends FunSuite {<br />
&lt;div style="padding: 0px 20px 0px 20px"&gt;test("") {<br />
&lt;div style="padding: 0px 20px 0px 20px"&gt;assert(true)&lt;/div&gt;<br />
}&lt;/div&gt;</code><code>}</code></div>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Guice</h3>
</div>
<p><a href="http://code.google.com/p/google-guice/" target="_blank">Guice</a> est un framework d&#8217;<a href="http://fr.wikipedia.org/wiki/Injection_de_d%C3%A9pendances" target="_blank">injection de dépendance</a> léger. Même si ce framework est Java à la base, il peut être utilisé dans du code Scala.</p>
<div style="margin-top:50px;margin-bottom:25px">
<h2>Emacs et les IDE</h2>
</div>
<p><a href="http://www.gnu.org/software/emacs/" target="_blank">Emacs</a> est un éditeur de texte assez ancien sans support de la complétion par exemple.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Alors pourquoi Emacs ?</h3>
</div>
<p><img style="float:right;margin-bottom:5px;margin-left:5px" title="EmacsSnapshot" src="http://www.gnu.org/software/emacs/tour/images/splash-small.png" alt="EmacsSnapshot" /> Alexandre aime bien Emacs qui est l&#8217;éditeur de référence du W3C. Il dispose d&#8217;une intégration avec SBT qui permet par exemple de se positionner dans le code à partir des messages d&#8217;erreur. Ce qui manque surtout c&#8217;est une intégration avec l&#8217;outillage de test. Il y a également un  module de templating de code pour Emacs,  <span style="color: #000000"><a href="http://code.google.com/p/yasnippet/" target="_blank">yasnippet</a>, </span> qui facilite l&#8217;écriture du code (<a href="http://www.scala-lang.org/node/354" target="_blank">vidéo de démo</a>)</p>
<p>Il n&#8217;a pas été convaincu par les plugins Scala des IDE comme Eclipse. Le typage est statique en Scala mais l&#8217;inférence de type donne parfois des résultats surprenants et complexes à déterminer pour les plugins. Les plugins ne gèrent pas toujours bien.</p>
<p>Les choses vont changer avec Scala 2.8 et la possibilité pour les IDE de s&#8217;interfacer avec le moteur Scala pour échanger des informations et faire de la complétion intelligemment.</p>
<p>De nouveaux outils arrivent et en particulier <a href="http://github.com/aemoncannon/ensime" target="_blank">ENSIME</a>, un projet Google Summer of Code, qui va proposer un nouvel environnement Scala pour Emacs. La vidéo de <a href="http://www.youtube.com/watch?v=A2Lai8IjLoY" target="_blank">démo</a> est très impressionnante.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Des alternatives ?</h3>
</div>
<p>D&#8217;autres personnes dans l&#8217;assistance utilisent Eclipse avec le plugin Scala et semblent en être contents. Vous pourrez trouver <a href="http://www.scala-lang.org/node/91#ide_plugins" target="_blank">ici</a> les plugins pour les différents IDE.</p>
<p>Francois Armand a également contribué sur la mailing list en fournissant des pointeurs pour utiliser Scala dans un environnement plus &#8220;familier&#8221;.</p>
<div style="margin-left:30px;margin-right:30px;padding-left:10px;padding-right:20px;padding-top:5px;padding-bottom:5px;background-color:#eeeeee">Il y a un plugin Scala pour eclipse, qui fonctionne de mieux en mieux (notez bien la tournure de la phrase). Il ne fonctionne qu&#8217;avec les dernière version de Scala (2.8), et il est dispo ici: <a href="http://www.scala-ide.org/" target="_blank">http://www.scala-ide.org/</a></p>
<p>Il y a aussi un plugin Maven/Scala, dispo ici: <a href="http://scala-tools.org/mvnsites/maven-scala-plugin/" target="_blank">http://scala-tools.org/mvnsites/maven-scala-plugin/</a></p>
<p>Et si tu veux vraiment télécharger plein de dépendances et faire du Scala-prêt-pour-l&#8217;entreprise, ca c&#8217;est le pom de base que j&#8217;utilise pour mes projets Scala: <a href="http://fanf42.blogspot.com/2010/05/maven2-bootstrap-pomxml-for-scala-with.html" target="_blank">http://fanf42.blogspot.com/2010/05/maven2-bootstrap-pomxml-for-scala-with.html</a></div>
<div style="margin-top:50px;margin-bottom:25px">
<h2>SBT &#8211; Simple Build Tool</h2>
</div>
<p><a href="http://code.google.com/p/simple-build-tool/" target="_blank">Simple Build Tool</a> est un outil dont la fonctionnalité est équivalente à <a href="http://maven.apache.org/" target="_blank">Maven</a> : Il réalise les tâches nécessaires à la fabrication du produit (compilation, tests, etc) et gère les dépendances via <a href="http://ant.apache.org/ivy/" target="_blank">Ivy</a>.</p>
<div style="float: right;width: 200px;margin: 5px 10px 5px 10px;padding: 5px 10px 5px 10px;background-color: #ffc7c7;text-align: justify"><a href="http://ant.apache.org/ivy/" target="_blank">Ivy</a> est un gestionnaire de dépendances. Il permet de trouver la version de librairie requise et de la télécharger dans le projet ainsi que ses dépendances. Ivy comme Maven gère un cache local.</div>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Pourquoi SBT ?</h3>
</div>
<p>SBT est plus léger que Maven. Pour Scala il est préférable car il ne recompile pas tout à chaque fois contrairement à Maven.</p>
<p>C&#8217;est un outil qui prend de l&#8217;importance. Les nouveaux projets du W3C sont faits sur SBT et plusieurs projets Open Source sont passés à SBT.</p>
<p>Il est utilisé en Scala ici mais marche aussi pour Java, ainsi que pour utiliser des frameworks Scala tels que Lift.</p>
<p><a href="http://jduchess.org/duchess-france/files/2010/05/sbt-tree-2.png"><img class="alignleft size-full wp-image-628" title="sbt-tree-2" src="http://jduchess.org/duchess-france/files/2010/05/sbt-tree-2.png" alt="sbt-tree-2" width="223" height="122" /></a>SBT a repris les mêmes conventions que Maven. La structure du projet est à peu près la même. La gestion de dépendances est un peu plus souple et permet par exemple d&#8217;utiliser un zip comme repository.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Comment configurer le projet SBT ?</h3>
</div>
<p>Contrairement à Maven qui est configuré via des fichiers XML, SBT est configuré<br />
via un fichier de propriétés <code>build.properties</code> qui spécifie entre autre les versions à utiliser et via une classe Scala <code>Project.scala</code> qui décrit les dépendances du projet.</p>
<div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code>import sbt._<br />
class Project(info: ProjectInfo) extends DefaultProject(info) {<br />
&lt;div style="padding: 0px 20px 0px 20px"&gt;val scalatools = "scala-tools" at "http://scala-tools.org/repo-snapshots"<br />
val scalatest = "org.scalatest" % "scalatest" % "1.0.1-for-scala-2.8.0.Beta1-with-test-interfaces-0.3-SNAPSHOT" % "test-&amp;gt;default"</p>
<p>val guice = "com.google.inject" % "guice" % "2.0"&lt;/div&gt;</code><code>}</code></div>
<p>Cette classe déclare deux dépendances avec ScalaTest, le framework de test unitaire, et Guice, le framework d&#8217;injection de dépendance.</p>
<p>La ligne <code>val "scala-tools" at "http://scala-tools.org/repo-snapshots"</code> est assez intéressante car elle montre la puissance de Scala pour faire des DSL.  Le <code>at</code> correspond à une méthode <code>at</code>. Mais une chaîne n&#8217;a pas de méthode <code>at</code>. Scala va chercher dans l&#8217;environnement, ici <code>DefaultProject</code>, une classe qui a une méthode <code>at</code> acceptant une chaîne et habiller la chaîne <code>"scala-tools"</code> pour en faire un instance de cette classe.<br />
On trouve des constructions équivalentes pour l&#8217;utilisation des expressions régulières, par exemple <code>"\(.*)@(.*)".r</code> .</p>
<p>Cette technique basée sur les conversions implicites est décrite sous le nom de <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=179766" target="_blank">Pimp my library</a> par Martin Odersky le créateur de Scala.</p>
<p>SBT utilise la version 2.7 de Scala par defaut dans sbt mais ont peut changer cette version dans <code>build.properties</code></p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Comment utiliser SBT ?</h3>
</div>
<p>SBT s&#8217;utilise en lançant la commande <code>sbt</code> qui ouvre un shell.</p>
<p>Les principales actions sont</p>
<ul>
<li><code>reload</code> : recharge les définitions du projet si elles ont changées</li>
<li><code>update</code> : résout les dépendances et retrouve les bonnes librairies. Elles sont copiées dans le projet mais Ivy gère également un cache local</li>
<li><code>test</code> : compile le code et les tests puis exécute les tests via une série de dépendances de tâches</li>
<li><code>test-only montest</code> permet de relancer automatiquement le test à chaque fois que le fichier est sauvé</li>
<li><code>run</code> : qui exécute une classe ou par défaut la seule classe avec un main</li>
</ul>
<p>On peut aussi définir ses propres goals et builder plusieurs cibles en même temps.</p>
<p>Si on a compris quelque chose de cette soirée, même quand on n&#8217;a pas trop d&#8217;expérience de Scala, c&#8217;est qu&#8217;il faut s&#8217;intéresser à SBT. Même Nicolas Martignole ( <a href="http://www.touilleur-express.fr/" target="_blank">Le Touilleur Express</a> ) a fait une intervention favorable en constatant que SBT fait moins peur pour la maintenabilité du build que <a href="http://www.gradle.org/" target="_blank">Gradle</a>.</p>
<div style="margin-top:50px;margin-bottom:25px">
<h2>Dans le vif du sujet</h2>
</div>
<p><a href="http://jduchess.org/duchess-france/files/2010/05/PSUG-mai-2.jpg"><img class="alignright size-full wp-image-629" title="PSUG-mai-2" src="http://jduchess.org/duchess-france/files/2010/05/PSUG-mai-2.jpg" alt="PSUG-mai-2" width="500" height="281" /></a>Bon là, ça se complique. Pour les gens qui ne connaissaient quasiment pas Scala, c&#8217;est allé très vite et comme les diverses stratégies d&#8217;implémentations n&#8217;étaient pas très bien balisées, on a été rapidement perdus.</p>
<p>Les prochaines sessions devraient être plus accessibles car il s&#8217;avère qu&#8217;il y a une forte proportion de gens sans expérience de Scala dans le groupe.</p>
<p>L&#8217;ensemble du code de la session est sur un repository <a href="http://mercurial.selenic.com/" target="_blank">Mercurial</a> <a href="https://dvcs.spartacusse.org/hg/di-scala">https://dvcs.spartacusse.org/hg/di-scala</a>. Si vous n&#8217;avez pas de client Mercurial, le lien zip en haut de la page permet de tout récupérer en un gros zip ou vous pouvez aussi <a href="https://dvcs.spartacusse.org/hg/di-scala/file/9f8d360d7c9f" target="_blank">lire les fichiers</a>.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>L&#8217;exemple de départ</h3>
</div>
<p><strong><span style="font-weight: normal">Dans tous les exemples, le code manipule un DVCSManager qui permet d&#8217;enregistrer une instance de DVCS (via save) et de la retrouver plus tard (via get).  Les tests utilisent une instance de type Mercurial (Hg) .</span></strong></p>
<p>Un peu de décodage sur le code de <a href="https://dvcs.spartacusse.org/hg/di-scala/file/9f8d360d7c9f/src/test/scala/Basic.scala" target="_blank"><code>Basic.scala</code></a></p>
<ul>
<li>En Scala, les noms de fichiers ne sont pas liés au nom de classe ou de package</li>
<li>Le fichier n&#8217;a pas a avoir le même nom que la classe, il peut y avoir plusieurs classes dans le même fichier</li>
<li>Le nom de package n&#8217;a pas besoin de correspondre à l&#8217;arborescence de répertoire sur disque</li>
<li>Les imports peuvent apparaître n&#8217;importe où dans le fichier</li>
</ul>
<p>Comme le code est destiné à une présentation, le test et le code sont dans le même fichier.</p>
<div style="float: right;width: 200px;margin: 5px 10px 5px 10px;padding: 5px 10px 5px 10px;background-color: #ffc7c7;text-align: justify">Les <em>traits </em>sont une sorte d&#8217;hybride entre des interfaces Java et des <a href="http://fr.wikipedia.org/wiki/Mixin" target="_blank"><em>mixins</em></a>.<br />
Ils permettent de décrire le comportement que devra implémenter la classe mais aussi de fournir des implémentations de méthodes qui seront greffées dans le code de la classe qui implémente le trait. Il est ainsi possible d&#8217;hériter de comportement de plusieurs classes différentes.<br />
Vous pouvez en apprendre plus avec ces deux ressources <a href="http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-5" target="_blank">en anglais</a> et <a href="http://blog.xebia.fr/2008/07/16/traits-scala/" target="_blank">en français</a>.</div>
<p>La première partie décrit les entités du domaine sous la forme de <em>traits</em>.</p>
<div style="float:left;margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code>trait Repository { val reponame:String }</code></div>
<p>Un trait très simple qui défini un repository générique et indique qu&#8217;il doit avoir un nom. Vous noterez que contrairement à Java le type suit le nom de la variable.</p>
<p>Un exemple un peu plus compliqué, le DVCSManager générique. L&#8217;implémentation réelle devra  fourir les 4 opérations listées en def.  <code>def</code> et <code>val</code> introduisent des membres du trait. La différence est que <code>def</code> permet la redéfinition alors que <code>val</code> ne le permet pas.</p>
<div style="float:left;margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code>trait DVCSManager {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;type T &amp;lt;: Repository<br />
def getAllRepositories():List[T]<br />
def save(repo:T):Unit<br />
def get(reponame:String):T<br />
def apply(reponame:String):T&lt;/div&gt;</code><code>}</code></div>
<p>Humm, un premier exemple de syntaxe bizarre Scala. <code>type T &amp;lt;: Repository</code> défini que le  <code>T</code> qui apparait dans les signatures des opérations qui suivent. <code>T</code> doit être une instance d&#8217;un type <code>T</code> dérivé de <code>Repository</code> mais son type réel sera défini plus tard. Cela ressemble vaguement à un générique pour le moment, mais il y a une différence subtile. Le type <code>T</code> ici est une classe bien particulière dont le choix est reporté et non pas quelque chose qui implémente <code>T</code> qui pourrait être différent d&#8217;une opération à l&#8217;autre.</p>
<div style="float: right;width: 200px;margin: 5px 10px 5px 10px;padding: 5px 10px 5px 10px;background-color: #ffc7c7;text-align: justify">Un <em>function object</em> est un objet que l&#8217;on peut utiliser comme une fonction.<br />
<a href="http://creativekarma.com/ee.php/weblog/comments/scala_function_objects_from_a_java_perspective/">Pour en savoir plus sur les function objects</a></div>
<p>La méthode <code>apply</code> a une signification un peu particulière. Elle donne à DVCSManager  la capacité d&#8217;être un <em>function object</em>. C&#8217;est ce qui permet d&#8217;écrire <code>val repo = DVCSManager("test")</code> dans le test. Le résultat sera d&#8217;initialiser le repository.</p>
<p>Le trait <code>HgManager</code> implémente le <code>DVCSManager</code> pour Mercurial.</p>
<div style="width: 600px;margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border: solid thin;border-color: grey"><code>trait HgManager extends DVCSManager {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;self: LDAPEnv with ApacheEnv with HgEnv =&amp;gt;<br />
type T = HgRepository<br />
val repos = scala.collection.mutable.Map[String, HgRepository]()<br />
def getAllRepositories():List[HgRepository] = repos.valuesIterator.toList<br />
def save(repo:HgRepository):Unit = { repos += (repo.reponame -&amp;gt; repo) }<br />
def get(reponame:String):HgRepository = repos(reponame)<br />
def apply(reponame:String):HgRepository = new HgRepository(reponame, this)&lt;/div&gt;</code><code>}</code></div>
<p>C&#8217;est ici que l&#8217;on va définir le type de <code>T</code> en écrivant <code>type T = HgRepositor</code>. La ligne <code>self: LDAPEnv with ApacheEnv with HgEnv =&amp;gt;</code> pose comme pré-condition à la création de l&#8217;instance qu&#8217;il existe dans l&#8217;environnement de la classe des instances de <code>LDAPEnv</code>, <code>ApacheEnv</code>,<code>HgEnv</code>. On ne pourra pas créer d&#8217;instance utilisant ce trait si ça n&#8217;est pas le cas.</p>
<p>Vous noterez le <code>this</code> dans   <code>new HgRepository(reponame, this)</code>. C&#8217;est la dépendance dont Alexandre voudrait bien se débarrasser en utilisant l&#8217;injection de dépendances.<br />
Le <code>self</code> permet une forme d&#8217;injection de dépendances avec en plus un contrôle plus fort sur le typage.</p>
<p>Pour finir avec le domaine, la classe qui implémente le repository Mercurial <code>HgRepository</code>. Il s&#8217;agit ici d&#8217;une véritable classe. <code>case class</code> la rend un peu plus Scala et apporte quelques facilités.</p>
<div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code>case class HgRepository(val reponame:String, env:LDAPEnv with ApacheEnv with HgEnv) extends Repository {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;// do some stuff using the environment<br />
println(env.hgrepodir.getAbsolutePath)&lt;/div&gt;</code><code>}</code></div>
<p>Cette classe a un constructeur à plusieurs arguments donc le second est une instance qui mixe <code>LDAPEnv</code>, <code>ApacheEnv</code> et <code>HgEnv</code>. Dans la section précédente, on voit que c&#8217;est un <code>HgManager</code> qui est passé. Par la présence du <code>self</code> on peut être sûr qu&#8217;il satisfait ces critères.</p>
<p>Le test ne préjuge pas du type de repository. Ce type est définit dans l&#8217;environnement.</p>
<div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code>test("") {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;val repo = DVCSManager("test")<br />
DVCSManager.save(repo)<br />
val persistedRepo = DVCSManager.get("test")<br />
assert(repo === persistedRepo )&lt;/div&gt;</code><code>}</code></div>
<p>Le <code>===</code> est équivalent à <code>==</code> en Java mais rend l&#8217;affichage de la comparaison plus lisible en indiquant aussi ce qui était attendu/reçu.</p>
<p>Diverses statégies ont été utilisées pour placer une instance de HgManager et des object &#8220;Env&#8221; dans l&#8217;environnement en limitant les dépendances.<br />
La forme la plus évidente est <code>val DVCSManager:DVCSManager = new HgManager with Env</code>. Il s&#8217;agit d&#8217;un mixin entre le <code>HgManager</code> et un trait <code>Env</code>. A noter on ne peut mixer que des traits.</p>
<p><code>Env</code> initialise les valeurs qui jusque là étaient seulement déclarées.</p>
<div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code> trait Env extends LDAPEnv with ApacheEnv with HgEnv {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;val hgrepodir:File = new File("/hgrepodir")<br />
val apachedir:File = new File("/apachedir")<br />
val ldapurl:String = "http://..."<br />
val ldapbinddn:String = "root"<br />
val ldapbindpassword:String = "pwd"&lt;/div&gt;</code><code>}</code></div>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Self et lazy</h3>
</div>
<p>Un premier essai de simplification a consisté à déplacer la création du <code>HgManager</code> dans <code>Env</code> comme on peut le voir dans <a href="https://dvcs.spartacusse.org/hg/di-scala/file/9f8d360d7c9f/src/test/scala/BasicBis.scala"><code>BasicBis.scala</code></a>. On pourrait dans ce cas se contenter de mixer Env avec le test.</p>
<div style="float: left;margin: 5px 10px 5px 10px;padding: 5px 10px 5px 10px"><span style="color: #ff0000"><span style="font-size:larger"><strong><em>BOUM !</em></strong></span></span></div>
<p>En fait, ça ne marche pas. Une dépendance cyclique apparaît. <code>Env</code> déclare <code>DVCSManager</code> qui a son tour a besoin de <code>Env</code>.</p>
<p>Pour éliminer la dépendance cyclique, il faut utiliser des &#8220;lazy val&#8221; comme dans <a href="https://dvcs.spartacusse.org/hg/di-scala/file/9f8d360d7c9f/src/test/scala/BasicSelfRef.scala"><code>ScalaSelfRef</code></a>. Mais ça introduit d&#8217;autres complications.</p>
<div style="float: left;margin: 5px 10px 5px 10px;padding: 5px 10px 5px 10px"><span style="color: #ff0000"><span style="font-size:larger"><strong><em>BOUM !</em></strong></span></span></div>
<p>Cette fois ci il ne trouve pas d&#8217;instance de HgRepository dans l&#8217;environnement alors qu&#8217;elle semble y être. Le self déclare seulement des types mais ne fournit pas d&#8217;implémentation. Le <code>new HgManager</code> n&#8217;a pas d&#8217;existence tant que le méthode n&#8217;est pas portée par une instance. Même si le <code>HgRepository</code> semble créé par <code>def apply(reponame:String):HgRepository = new HgRepository(reponame) with LDAPEnv with ApacheEnv with HgEnv</code>, il faut quand même instancier explicitement le HgManager par <code>val DVCSManager:DVCSManager = new HgManager with Env</code>. </p>
<p>Cet exemple pas à pas montre qu&#8217;il n&#8217;est pas toujours évident de comprendre quel type seront inférés et si une instance convenable sera trouvée ou pas dans l&#8217;environnement.</p>
<p>Une constatation est que le modèle marche bien tant que l&#8217;on est dans des cas de figure simples avec des new partout. Mais les factories posent problème.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Cake pattern</h3>
</div>
<p>Là j&#8217;ai été un peu larguée. N&#8217;ayant pas révisé le Cake Pattern à l&#8217;avance, je ne m&#8217;avancerai pas à retranscrire les débats dans le détail.</p>
<p>Vous pourrez trouver l&#8217;exemple de code dans <a href="https://dvcs.spartacusse.org/hg/di-scala/file/9f8d360d7c9f/src/test/scala/CakePattern.scala"><code>CakePattern.scala</code> </a><br />
L&#8217;initialisation de l&#8217;environnement est maintenant à la charge du &lt;code&gt;ComponentRegistry&lt;/code&gt;.</p>
<p>Un bon point de départ est l&#8217;<a href="http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html" target="_blank">article</a> de Jonas Bonér sur les diverses techniques d&#8217;injection de dépendance. Il contient également la référence sur l&#8217;article initial de Martin Odersky, le créateur de Scala.</p>
<p>Le principe du Cake Pattern est de créer un composant qui encapsulent les environnement dont on a besoin. Tout ça fait une sorte de mille-feuille. Si on regarde, le code exemple chaque trait ou classe reçoit un composant qui l&#8217;englobe.</p>
<p>Ce modèle simplifie les choses pour celui qui utilise les composants car il n&#8217;a plus de besoin de mixins et peut se reposer sur le choix de celui qui a fait le composant.  Mais est lourd à implémenter pour celui qui fournit les composants.</p>
<p>ScalaDoc a beaucoup utilisé le Cake pattern et en est un peu revenu car c&#8217;est difficile à maintenir. Ce modèle a tendance a créer un objet qui fait tout avec des tas de fonctions externes autour.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Closure</h3>
</div>
<p>Un autre modèle basé sur des closures à été évoqué. Il est décrit par Debashishg Gosh dans cet <a href="http://debasishg.blogspot.com/2010/02/dependency-injection-as-function.html" target="_blank">article</a>.</p>
<p>L&#8217;exemple de code qui correspond est <code><a href="https://dvcs.spartacusse.org/hg/di-scala/file/9f8d360d7c9f/src/test/scala/Closure.scala" target="_blank">Closure.java</a>.</code></p>
<p>La closure se trouve là</p>
<p><code>&lt;div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"&gt;trait HgManager extends DVCSManager {<br />
...<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;def apply(_reponame:String):HgRepository = new HgRepository {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;val reponame:String = _reponame<br />
lazy val env = self&lt;/div&gt;<br />
}&lt;/div&gt;<br />
}&lt;/div&gt;</code></p>
<p>Le principe est plus proche de Java. On passe un objet avec des trous qu&#8217;on complètera plus tard.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Guice</h3>
</div>
<p>Le code qui illustre l&#8217;utilisation de Guice est dans <code>Guice.scala</code></a></p>
<p>Le code a été modifié pour s&#8217;intégrer à Guice et fini par ressembler beaucoup à un java.</p>
<p><code> </code></p>
<div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"><code> class HgManager @Inject() () extends DVCSManager {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;self: MixedEnv =&amp;gt;<br />
...<br />
@Inject val hgRepoFactory:HgRepositoryFactory = null<br />
def apply(reponame:String):HgRepository = hgRepoFactory.create(reponame)&lt;/div&gt;</code><code>}</code></div>
<p>Guice est parfois un peu perdu car une classe Scala peut générer beaucoup de classe Java et Guice ne sait pas toujours laquelle utiliser.</p>
<div style="margin-top:30px;margin-bottom:15px">
<h3>Structural Typing</h3>
</div>
<p>L&#8217;exemple utilisant le <a href="http://scala.sygneca.com/patterns/duck-typing-done-right">structural typing</a> est dans <code>StructuralTyping.scala</code></p>
<p><code>&lt;div style="margin: 0px 10px 0px 10px;padding: 5px 10px 5px 10px;border:solid thin;border-color: grey"&gt;abstract class ToBeTested extends FunSuite {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;self: { val DVCSManager:DVCSManager } =&amp;gt;</p>
<p>test("") {<br />
&lt;div style="padding: 0px 10px 0px 10px"&gt;val repo = DVCSManager("test")<br />
DVCSManager.save(repo)<br />
val persistedRepo = DVCSManager.get("test")<br />
assert(repo === persistedRepo)&lt;/div&gt;<br />
}&lt;/div&gt;<br />
}<br />
class Test extends ToBeTested with Env&lt;/div&gt;</code><br />
Le structural typing est <code>{ val DVCSManager:DVCSManager } =&amp;gt;</code>. C&#8217;est une sorte de duck typing.<br />
C&#8217;est un moyen d&#8217;éviter de créer un trait juste pour positionner cette valeur. Mais cette technique a pour inconvénient de reposer totalement sur la Reflection Java  et pose des problèmes de performance.</p>
<div style="margin-top:50px;margin-bottom:25px">
<h2>Conclusion</h2>
</div>
<p>Aucune des solutions n&#8217;est totalement satisfaisantes. Quelques méthodes à la Java fonctionnent bien mais perdent la simplicité d&#8217;écriture de Scala. Les solutions plus Scala fonctionnent dans les cas simples mais sont conçues pour faire des new sans utiliser de factory. Les comportements peuvent être différents en fonction de l&#8217;ordre d&#8217;initialisation.<br />
Si on pousser trop loin l&#8217;injection de dépendance, ça devient compliqué</p>
<p>La spécification <a href="http://jcp.org/en/jsr/detail?id=330">JSR330</a> sur l&#8217;injection de dépendance pourrait améliorer les choses en apportant le support de l&#8217;injection de dépendance directement dans la JVM.</p>
]]></content:encoded>
			<wfw:commentRss>http://jduchess.org/duchess-france/blog/psug1-la-premiere-du-scala-user-group/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 3/22 queries in 0.176 seconds using disk: basic
Object Caching 346/361 objects using disk: basic

Served from: jduchess.org @ 2012-02-09 08:13:20 -->
