<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>Page de Geek</title>
		<description>Un blog où l'on parle des technologies web</description>
		<link>http://www.pagedegeek.com</link>
		
			<item>
				<title>Thème ParisInBlue pour MacVim</title>
				<description>&lt;p&gt;
  &lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/parisinblue.jpg&quot;/&gt;&lt;/p&gt;
Je viens de publier un nouveau thème pour vim. Toujours principalement destiné à coder en Ruby même si ok sur d&amp;#8217;autres languages.
&lt;br/&gt;Il est téléchargeable ici:
&lt;a href=&quot;https://github.com/PagedeGeek/my-vim-themes/blob/master/parisinblue.vim&quot;&gt;vim parisinblue&lt;/a&gt;.
&lt;p/&gt;</description>
				<link>http://www.pagedegeek.com/2012/11/13/theme-vim-parisinblue.html</link>
			</item>
		
			<item>
				<title>Thème ParisInLove pour MacVim</title>
				<description>&lt;p&gt;
  &lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/parisinlove.png&quot;/&gt;&lt;/p&gt;
Je viens de publier un thème pour vim. Principalement destiné à coder en Ruby et avec RubyOnRails.
&lt;br/&gt;Il est téléchargeable ici:
&lt;a href=&quot;https://github.com/PagedeGeek/my-vim-themes/blob/master/parisinlove.vim&quot;&gt;vim parisinlove&lt;/a&gt;.
&lt;p/&gt;</description>
				<link>http://www.pagedegeek.com/2012/11/12/theme-vim-parisinlove.html</link>
			</item>
		
			<item>
				<title>Google bot est passé</title>
				<description>&lt;p&gt;
Ce weekend, après la nouvelle version du blog,
j&amp;#8217;ai réussi à faire venir Google Bot assez rapidement.
La preuve, je l&amp;#8217;ai même pris en photo ;)
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/google-bot-2.jpg&quot;/&gt;&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/google-bot-1.jpg&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
Vous pouvez retrouver d&amp;#8217;autres éléments en papier sur:
&lt;a href=&quot;http://rommy.kamimodel.com/index_e.html&quot; rel=&quot;nofollow&quot;&gt;Sloth Paper Toys &lt;span class=&quot;caps&quot;&gt;ROMMY&lt;/span&gt;&lt;/a&gt;
&lt;p&gt;</description>
				<link>http://www.pagedegeek.com/2012/11/12/google-bot-papier.html</link>
			</item>
		
			<item>
				<title>Coup de pinceau</title>
				<description>&lt;p&gt;
Vous l&amp;#8217;aurez constaté, j&amp;#8217;ai complétement redessiné le design du blog.
&lt;br/&gt;Je souhaitai rester sur une approche très verticale facilitant la lecture des articles.
Je pense que cet objectif est atteint.
&lt;br/&gt;Concernant le design, il reste clair et exploite des textures rappelant des tissus et donnant, j&amp;#8217;espère, un effet &amp;#8220;rétro&amp;#8221;.
J&amp;#8217;ajouterai bientôt quelques nouveaux éléments dans le même esprit permettant de donner plus de profondeur.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/devant-apple-store-paris.jpg&quot;/&gt;&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/11/11/coup-pinceau.html</link>
			</item>
		
			<item>
				<title>Multiples connexions avec ActiveRecord</title>
				<description>&lt;p&gt;
Il y a quelque jours j’étais tombé sur un article présentant une technique permettant à du code Ruby de s’interconnecter, en exploitant Active Record, à plusieurs bases de données.
Ceci peut être très intéressant lorsqu’on a du code backend ou de gestion de données en tache de fond.
Ou encore, lors de reprises de données.
Il est par exemple possible de charger des objets sur une base MySQL et avec d’autres sur du Posgres.
Par contre niveau performance, il ne faut pas se voiler la face, ce n’est pas la meilleure solution.
&lt;/p&gt;
&lt;p&gt;
Je livre donc le code tel quel. Dans mon exemple, on a bien entendu sur la db1 une table « articles » avec une colonne « category_id », et sur la db2 une table « categories ».
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;db_one&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;mysql2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;localhost&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;root&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;db1&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;utf8&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;db_two&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;mysql2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;localhost&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;root&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;db2&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;utf8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;yaml&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;active_record&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# récupération du fichier de configuration des bases de données&lt;/span&gt;
&lt;span class=&quot;vg&quot;&gt;$config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YAML&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;config.yml&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# définition des bases de données&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Db1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstract_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;establish_connection&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;db_one&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Db2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstract_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;establish_connection&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;db_two&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# définition des objets métier. Ils héritent de Db(x)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Article&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Db1&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;belongs_to&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:category&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Db2&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;has_many&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:articles&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# utilisation des objects&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Article&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;- &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2012/10/28/multiple-connexion-active-record-ruby.html</link>
			</item>
		
			<item>
				<title>Avantage de Map Reduce</title>
				<description>&lt;p&gt;
&lt;p&gt;Depuis déjà quelques temps le Big Data est la mode. Certains font un discours commercial sur ce sujet, d’autres en font une véritable rupture technologique. Certains le résument à de la visualisation graphique… Quelque soit les points de vue, il s’agit toujours de problématiques reposant sur le traitement de données volumineuses.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;D’un point de vue très technique, il existe plusieurs techniques pour traiter des données massives. L’une d’elle se nomme Map/Reduce que je vais essayer de présenter ici en utilisant Ruby.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Wikipedia nous dit que Map/Reduce correspond à un framework présenté par Google et permettant d’effectuer des traitements parallèles le plus souvent distribués sur plusieurs machines. Par données volumineuse, il faut comprendre &amp;gt; à 1 To.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans cette définition, le terme framework me gêne. En effet, il existe des technologies comme Hadoop implémentant Map/Reduce et proposant différents services supplémentaires. Toutefois, à mon sens, je considère plus Map/Reduce comme une approche, voir un Pattern, plus qu’un framework « clé en main ».&lt;br /&gt;
Je vais essayer de montrer que Map/Reduce peut être implantée « facilement » sans avoir recours à un framework.&lt;br /&gt;
Lors du traitement massif de données, le développeur doit changer son point de vue sur ses travaux, ses techniques et ses « outils ». En effet, la conception d’un système devant traiter xTo de données, qui vont surement augmenter dans le temps, n’est pas la même chose que de développer une application web reposant sur une base de données classique proposant des systèmes d’index. A ce niveau des enjeux de scalabilité doivent aussi être pris en compte. C’est ce que permet Map/Reduce.&lt;/p&gt;
&lt;/p&gt;
&lt;h4&gt;Le problème en détail&lt;/h4&gt;
&lt;p&gt;
&lt;p&gt;Admettons que j’ai un corpus de données à traiter. Il s’agit de tweets.&lt;br /&gt;
Pour résumer ces données je veux me concentrer sur les hashtags qu’ils comportent. C’est à dire les extraire et les compter. Ceci me permettra par exemple de voir ceux qui font le plus « buzz » sur un période de temps.&lt;br /&gt;
La logique voudrait que je réalise une « petite boucle » qui passe en revue chaque tweet, leur applique une fonction de traitement (voir de normalisation et de nettoyage), puis extrait les hashtags vers un tableau.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Le problème est que le nombre de tweets est plutôt important. Le fichier se compte en Go de données (pour info. ce chiffre est rapidement atteignable avec l’API Twitter). La solution sera donc d’augmenter la taille de la machine de traitement. Ce qui augmentera les performances de « ma boucle ». Admettons que je puisse traiter 1Go de tweets en 5 secondes.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;J’ai codé cette approche au sein d’un projet sur Github :&lt;br /&gt;
&lt;a href=&quot;https://github.com/PagedeGeek/poc-map-reduce/blob/master/lib/db_strategies/one_big_file.rb&quot;&gt;one_big_file.rb&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Ce code se contente de charger en mémoire un fichier « important » et d’extraire chaque tweet. Point important : les contraintes de temps de traitement d’un fichier « important » sont codées par une classe de simulation. J’allais tout de même pas pousser 1Go de données sur Github :).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Problématique supplémentaire importante : dans le futur ce corpus de données va obligatoirement augmenter avec le nombre de tweets toujours plus important. Ce qui pose problème à ce niveau, c’est qu’il n’y a pas de limite de volumétrie des données mais une limite sur la taille des machines de traitement sur lequel on ne peut pas agir.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Map/Reduce permet de répondre de façon intéressante à ce problème.&lt;br /&gt;
Ci-dessus nous avons admis qu’il est possible de traiter 1Go de tweets en 5 secondes. Je souhaite réduire le temps de traitement total acceptable à une seconde. Par hypothèse, je vais donc « splitter » ce fichier volumineux en 5 autres plus petits.&lt;br /&gt;
Il s’agit donc de découper le problème en sous-problèmes puis de les déléguer (fonction Map) à des « nœuds » indépendants (de préférence répartis sur plusieurs machines). Chaque nœud, remontera ses résultats au nœud parent.&lt;br /&gt;
Par la suite, il va falloir « réduire » (fonction Reduce) chaque résultat et reconstruire un résultat commun dans la forme attendue.&lt;br /&gt;
C’est le code présenté ici :&lt;br /&gt;
&lt;a href=&quot;https://github.com/PagedeGeek/poc-map-reduce/blob/master/lib/db_strategies/map_reduce/with_threads.rb&quot;&gt;map_reduce_with_threads.rb&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans ce fichier source, le temps de traitement des petits fichiers est aussi simulé. J’ai exploité les threads pour « distribuer » les traitements sur plusieurs nœuds. Chaque thread est en quelque sorte un nœud. Il est important de noter que dans la vie réelle, chaque nœud devrait être sur une machine séparée. Ceci aurait plusieurs avantage : si une machine tombe, une autre peut prendre le relai. De plus, si la volumétrie de données augmente, il suffit d’ajouter des machines.&lt;br /&gt;
Les threads ne seraient donc pas utilisés.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Pour conclure, dans ce billet, j’ai essayé de présenter l’approche Map/Reduce qui répond vraiment aux problématiques actuelles.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Globalement, le code source peut être cloné (&lt;a href=&quot;https://github.com/PagedeGeek/poc-map-reduce.git&quot;&gt;https://github.com/PagedeGeek/map_reduce_poc.git&lt;/a&gt;) et testé en utilisant le fichier bin/hashtags.rb avec différents paramètres.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Ce client exploite quelque chose proche d’un design pattern Strategy en mesure de charger les deux approches présentées ci-dessus : chargement par un seul fichier volumineux, ou par un plusieurs plus petits fichiers.&lt;br /&gt;
J’essaierais d’implémenter rapidement une troisième stratégie reposant sur un véritable système de distribution de taches. Au hasard : Redis :)&lt;/p&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/08/12/avanage-map-reduce.html</link>
			</item>
		
			<item>
				<title>Revue de liens</title>
				<description>&lt;p&gt;
&lt;p&gt;Voici quelques liens que j&amp;#8217;ai partagé cette semaine sur différents réseaux:&lt;/p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[Text Mining] &lt;a href=&quot;http://pgsimilarity.projects.postgresql.org/&quot;&gt;pg_similarity is an extension to support similarity queries on PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Data Analysis] &lt;a href=&quot;http://viksalgorithms.blogspot.com.au/2012/06/tracking-us-sentiments-over-time-in.html&quot;&gt;Tracking US Sentiments Over Time In Wikileaks &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Web-Marketing] &lt;a href=&quot;http://www.decideo.fr/Le-Marketing-Intelligent-depoussiere-le-marketing-relationnel_a5290.html&quot;&gt;Le Marketing Intelligent dépoussière le marketing relationnel &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[&lt;span class=&quot;caps&quot;&gt;SEO&lt;/span&gt;] &lt;a href=&quot;http://lemusclereferencement.com/2012/06/21/la-personnalisation-des-resultats-explique-a-lionel-dricot/&quot;&gt;La personnalisation des résultats expliquée&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Startups] &lt;a href=&quot;http://www.guilhembertholet.com/blog/2012/06/19/pourquoi-les-startups-echouent-elles/&quot;&gt;Pourquoi les startups échouent-elles ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Search Engine] &lt;a href=&quot;http://www.mti.epita.fr/blogs/2012/06/14/le-moteur-de-recherche-dapache-lucene-et-son-projet-solr/&quot;&gt;Le moteur de recherche d’Apache Lucene et son projet Solr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Techno.] &lt;a href=&quot;http://rediscookbook.org/using_a_ruby_library_to_store_objects.html&quot;&gt;Redis Cookbook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2012/06/24/liens-partages-semanine.html</link>
			</item>
		
			<item>
				<title>Mode Vintage de Sublime Text 2</title>
				<description>&lt;p&gt;
Mon passage sous Mac remonte à 2006 avec l’arrivée des MacBook Pro sur la base d’architecture Intel.&lt;br/&gt;
&lt;p&gt;Depuis ce temps, je n’ai jamais quitté cette plateforme. Auparavant, j’ai longtemps utilisé Linux. Principalement avec les distributions Fedora. Je me souviens être longtemps resté sur une Fedora Core 4 supporté par un vieux ThinkPad d’IBM. Le couple avait le mérite d’être increvable. Tous les pilotes fonctionnaient à merveille, la puissance était vraiment à l’ordre du jour.&lt;br /&gt;
Sur cet environnement, j’ai un peu utilisé Eclipse, travaillant sur les technologies Java, &lt;span class=&quot;caps&quot;&gt;JEE&lt;/span&gt; notamment avec la sortie des EJB3 ; mais j’ai très souvent exploité &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt; pour éditer du code source.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Sur Mac, j’ai suivi l’effet de mode. Je me suis mis à Textmate. Cet éditeur par sa philosophie est plus proche de Vim que d’Eclipse. Il avait le net avantage d’être très léger et proposer une richesse fonctionnelle impressionnante. La productivité offerte par Textemate est rendue possible grâce à sa quantité importante et intelligente de raccourcis clavier, de snippets et autres systèmes customizable.&lt;/p&gt;
&lt;h3&gt;Avantages de Vim&lt;/h3&gt;
&lt;p&gt;Vim offre une fonctionnalité que j’ai longtemps exploitée mais que, malheureusement, TextMate ne propose pas. Il s’agit du Split de fenêtre.&lt;br /&gt;
Par exemple, le Split Vertical permet d’ouvrir deux pages de source afin de les éditer en même temps. Cette fonctionnalité est extrêmement pratique dans le cadre du développement de tests unitaires. En effet, sur la split principal j’aime avoir le code source de travail puis sur l’autre partie mes tests unitaires correspondant à ce code. Ce qui permet de switcher rapidement entre les deux au moyen d’un seul coup d‘œil sans avoir besoin de changer d’onglet.&lt;br /&gt;
Sous Ruby on Rails, avoir sur le split principal ses controller, puis l’autre split de ses vues est ausi une bonne idée. Dans un autre onglet, on peut imaginer avoir ses models ainsi que ses tests unitaires sur deux splits différents.&lt;br/&gt;
Je ne vais pas rentrer dans les détails. Chaque développeur à ses petites manies. Quoiqu’il en soit l’exploitation du mode splits permet d’être productif.&lt;/p&gt;
&lt;p&gt;Au delà de cette fonctionnalité ergonomique, Vim à la particularité d’offrir à l’utilisateur deux modes. Le mode édition et le mode visualisation. Le premier mode propose d’éditer son code source de la même façon que tous les autres éditeurs en proposant même un système de complétion automatique. Le second mode, très difficile à prendre en main, mais tellement puissant, permet à l’utilisateur d’agir sur son code source au moyen de raccourcis clavier en laissant complémentent de coté la souris. Par exemple : se déplacer dans le code source au moyen des touches H, J, K, L, etc.&lt;br /&gt;
Je ne rentre pas non plus dans les détails, beaucoup d’articles discutent sur la nécessité de cette approche et en quoi elle est bénéfique pour les développeurs.&lt;/p&gt;
&lt;h3&gt;Inconvénient de Vim sous Mac&lt;/h3&gt;
&lt;p&gt;Cependant, Vim sous Mac, particulièrement avec MacVim, a le désagréable problème de ramer légèrement lorsque le code source fait plus de 300 lignes de code. Je ne connais pas vraiment l’origine de ce problème. Toutefois, une utilisation quotidienne permet de ressentir ce souci qui dans certains cas peut devenir rapidement agaçant.&lt;/p&gt;
&lt;h3&gt;Sublime Text 2 mode Vintage&lt;/h3&gt;
&lt;p&gt;Un ami (Florien tu te reconnaitras), m’a souvent parlé de Sublime Text 2.&lt;br /&gt;
Cet éditeur de code source propose, à la différence de TextMate, le split vertical et horizontal. Pour le reste, ils sont sensiblement équivalent : léger, riche sur le plan fonctionnel et customizable.&lt;/p&gt;
&lt;p&gt;En rentrant un peu en profondeur dans les capacités de Sublime Text 2, j’ai découvert que cet éditeur de code proposait le mode « Vintage » !&lt;br /&gt;
Ceci correspond tout à fait à ce que Vim propose. C’est à dire la possibilité d’avoir deux modes : visualisation et édition.&lt;/p&gt;
&lt;p&gt;Le mode Vintage de Sublime Text 2 peut être activé au moyen de l’édition des dernières lignes du ficher de configuration par défaut. Il suffit de le retirer des packages ignorés. Ce qui donne :&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;// List any packages to ignore here. When removing entries from this list,
// a restart may be required &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;the package contains plugins.
&lt;span class=&quot;s2&quot;&gt;&amp;quot;ignored_packages&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;,
&lt;span class=&quot;s2&quot;&gt;&amp;quot;vintage_start_in_command_mode&amp;quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Dès lors, il est possible dans Sublime Text 2, d’avoir accès aux capacités spéciales des deux modes. Dorénavant, vous pouvez vous déplacer grâce aux touches &lt;span class=&quot;caps&quot;&gt;HJKL&lt;/span&gt;. Vous déplacer entre plusieurs mots avec E, W, B, etc.&lt;/p&gt;
&lt;p&gt;Vous pouvez aussi étendre les raccourcis clavier. Par exemple pour switter entre les splits verticaux, changer l’accès au système de complétion automatique, jouer avec la sidebar, etc.&lt;br/&gt;
Ce qui donne pour moi, dans le fichier User Key Binding :&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;// &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ctrl+l&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;focus_group&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;group&amp;quot;&lt;/span&gt;: 1&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ctrl+l&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;next_view&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
// &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ctrl+h&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;focus_group&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;group&amp;quot;&lt;/span&gt;: 0&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ctrl+h&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;prev_view&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ctrl+k&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;scroll_lines&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;amount&amp;quot;&lt;/span&gt;: 15.0&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ctrl+j&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;scroll_lines&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;amount&amp;quot;&lt;/span&gt;: -15.0&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,

&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;super+shift+k&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;toggle_side_bar&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;super+shift+h&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;focus_side_bar&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;keys&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;super+shift+l&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;focus_group&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;group&amp;quot;&lt;/span&gt;: 0&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Petit bonus&lt;/h3&gt;
&lt;p&gt;Je vous propose aussi une nouvelle &lt;a href=&quot;/images/Sublime Text 2.icns&quot;&gt;icone Sublime Text 2&lt;/a&gt; (version Mac). &lt;a href=&quot;/images/Sublime_text_2.ico&quot;&gt;Version Windows&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;
&lt;center&gt;
&lt;img src=&quot;/images/subl.png&quot; alt=&quot;icon Sublime Text 2&quot;/&gt;
&lt;/center&gt;
&lt;p&gt;&amp;lt;/&amp;gt;&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/06/21/Sublime-text-mode-vintage.html</link>
			</item>
		
			<item>
				<title>Pousser ses logs Ruby dans Redis</title>
				<description>&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/queue_redis.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Il y a quelques mois j’ai réalisé un billet sur les avantages d’utiliser &lt;a href=&quot;/2012/02/25/puts-vs-logger.html&quot;&gt;Logger avec Ruby&lt;/a&gt; plutôt que les méthodes « puts ».&lt;br /&gt;
Je présentais qu’il était aisément possible d’implémenter un « Logger Device » en mesure d’absorber les logs puis de les traiter par exemple en les injectant dans une base sqlite3.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Hier soir, j’ai réalisé un Gem facilitant ce travail dans le but de pousser les &lt;a href=&quot;https://rubygems.org/gems/redis_logger_device&quot;&gt;logs dans une Queue Redis&lt;/a&gt;.&lt;br /&gt;
Son utilisation est très simple. Il faut 1° mettre en place le device dans son code lors de la création du logger, puis dans un second temps coder un worker qui viendra régulièrement traiter les logs. Dès lors, il est possible de lancer différents workers en parallèle.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
Pour l&amp;#8217;installer, la procédure est classique:&lt;br/&gt;
$ gem install redis_logger_device
&lt;/p&gt;
&lt;h3&gt;Code d&amp;#8217;utilisation&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;logger&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;redis_logger_device&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;dev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RedisLoggerDevice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;AAAAAaaaaaahhhhh&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Un simple Worker&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Attention, ce code traite les logs de la queue redis mais exploite aussi un logger en &lt;span class=&quot;caps&quot;&gt;STDOUT&lt;/span&gt; (worker_logger) qui n&amp;#8217;a rien à voir avec le premier. A ne pas confondre :)&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;logger&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;redis_logger_device&amp;#39;&lt;/span&gt;

&lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RedisLoggerDevice&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SimpleLogWorker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LogWorker&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_queue!&lt;/span&gt;
    &lt;span class=&quot;kp&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;LogWorker fetching (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@queue_name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;brpop&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@queue_name&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;LogWorker rocess key: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; val: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;#your code : val = log entry&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;LogWorker error: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;worker_logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SimpleLogWorker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;worker_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_queue!&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;worker_looger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Ce Gem est fonctionnelle. Il exploite le mode &amp;#8216;List&amp;#8217; de Redis. Je pense cependant apporter quelques améliorations rapidement, notamment en expoitant le mode PubSub.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/06/01/redis-logger-device.html</link>
			</item>
		
			<item>
				<title>Diffusion de liens</title>
				<description>&lt;p&gt;
Ce blog me permet depuis presque un an de partager différents points de vu technique notamment concernant
les bonnes pratiques de développement (Design Pattern, tests unitaires, etc.), les technologies liées à l&amp;#8217;univers Ruby,
Big Data, NoSQL, Calculs distribués, sécurité et d&amp;#8217;autres thématiques.
&lt;/p&gt;
&lt;p&gt;
J&amp;#8217;essaie de détailler au maximum mes billets. Cependant, au regard du temps passé sur ces publications, je pense diffuser de plus en plus de liens brutes, sans trop d&amp;#8217;analyse.
Les thématiques resteront donc les mêmes mais seront d&amp;#8217;avantages ouvertes vers le Web Analytics et le &lt;span class=&quot;caps&quot;&gt;SEO&lt;/span&gt;.
&lt;br/&gt;
Je commence donc par ces élélements:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.kissmetrics.com/guide-to-facebook-insights/&quot;&gt;Guide to Facebook insights&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://gigaom.com/cloud/monetizing-social-media-means-navigating-big-sucky-data/&quot;&gt;Monetizing social media means navigating ‘big, sucky data’&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://funnel.hasgeek.com/5el/323-the-redis-way-of-analytics&quot;&gt;The Redis way of analycis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2012/05/31/diffusion-de-liens.html</link>
			</item>
		
			<item>
				<title>Exercice de scalabilité avec Ruby et Redis</title>
				<description>&lt;p&gt;Il y a quelques jours, j’ai découvert un peu par hasard que certains des flux &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; que je suivais étaient mort ou avaient changé d’url.&lt;/p&gt;
&lt;p&gt;Malheureusement peu d’outils (dont Google Reader) informent l’utilisateur de ce problème.&lt;br /&gt;
Lorsque l’on fait de la veille, c’est très embêtant de penser suivre un corpus de flux rss quand bien même ils peuvent changer.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Prenant le train, je me suis mis à coder rapidement un p’tit outil en mesure de détecter les éventuels flux morts.&lt;br /&gt;
En effet, je souhaitais identifier les flux provoquant une erreur &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; (404 et autre) ou ne proposant plus aucun article.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Avec Ruby il existe la Gem feedzirra et la lib standard &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt;. Pour des raisons pratiques, j’ai choisi&amp;#8230; les deux :)&lt;br /&gt;
En effet, j’ai eu du mal à me décider. J’ai donc appliqué le Design Pattern Strategy en mesure de sélectionner l’une ou l’autre méthode de collecte de flux &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt;.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Avec quelques méthodes d’import de flux à partir d’un fichier &lt;span class=&quot;caps&quot;&gt;OPML&lt;/span&gt;, ca donne ce code :&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;logger&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rss&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;nokogiri&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FeedsEngine&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NotImplemented&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;StandardEngine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FeedzirraEngine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;feedzirra&amp;#39;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Process url &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Feedzirra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch_and_parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Url processed: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;404&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Error 404&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Entry found: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; entries in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Warning: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardEngine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Process url &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Url processed: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;rss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RSS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;rss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Entry found: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; entries in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Warning: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OpmlImporter&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;urls&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;OpmlImporter open file: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@filename&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;outlines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nokogiri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;outline&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;outlines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;xmlurl&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
          &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;OpmlImpoter add url: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; 

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;OpmlImporter error: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cli&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;info&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;use ./feedschecker.rb OPML_FILENAME LOG_LEVEL&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;info&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;info&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;WARN&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;warning&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ERROR&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./bad_feeds.txt&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;no&quot;&gt;OpmlImporter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ERROR: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Points d’amélioration avec le multihreading&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;Ce code fonctionne assez bien lorsque l’on analyse une centaine de flux &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt;. L’outil tourne sur chaque élément, réalise les requêtes http, traite les résultats, puis pousse les retours d’erreurs vers l’utilisateur.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Cependant à partir de 1000 flux &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt;, ce fonctionnement commence à devenir un peu (trop) long.&lt;br /&gt;
Les délais de traitement les plus grand sont sur la couche de communication réseau. Certains serveurs répondent rapidement, d’autres avec des délais plus long.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;L’idée est donc de paralléliser les traitements en exploitant les modes multithreading ou une approches à base de processus système.&lt;br /&gt;
Ceci afin de ne pas engendrer de blocage et de latence par les serveurs les plus médiocre.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;L’approche classique serait de modifier le code afin de mettre en place des pool de flux &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; importés puis de lancer des threads (ou processus) en parallèle afin de diminuer les temps de collecte. Les threads seront à privilégier car étant plus léger et moins gourmant que les processus système.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Toutefois, j’ai choisi une approche de parallélisassions des traitements différente.&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Distribution, parallélisassions et scalabilité avec Redis&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;J’ai fait le choix d’utiliser un système reposant sur une Queue centrale en mesure du distribuer les taches à effectuer aux différents systèmes de collecte et de traitement.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Ceci à l’énorme avantage de faciliter la scalabilité horizontale et donc de répartir les travaux sur plusieurs machines (et aussi sur plusieurs réseaux mais c’est une autre histoire :).&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Avec cette approche, on peut découper les traitements. Il est possible d’avoir des systèmes dédiés à la collecte des flux &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt;, d’autres aux calculs.&lt;br /&gt;
Dans notre cas, seul compte l’identification du nombre d’articles par flux rss et la détection d’erreur. Toute « l’intelligence » peut donc être concentrée dans chaque sous-système, au même endroit.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;De plus, avoir un système facilitant la scalabilité horizontale permet de gérer en temps réel l’activité de plusieurs machines. Par exemple, si le nombre de flux rss augmente rapidement il est possible d’allouer dynamiquement des ressources permettant de faire face à cette charge ponctuelle.&lt;br /&gt;
Au contraire si le nombre de flux rss à analyser est faible, on peut transformer des systèmes initialement dédiés à la collecte, aux activités de traitement.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Je ne détail pas le fait que le système est très flexible face aux pannes.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;L’architecture repose donc sur la mise en place d’un serveur Redis faisant office de Queue.&lt;br /&gt;
Afin de contenir d’éventuels problèmes techniques, ce serveur peut être identifié comme Master et faire appel à des Slaves dans une architecture en cluster par exemple. Je ne détail pas, Google est votre ami :)&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Le serveur Redis peut aussi être installé sur sa machine en local, ou sur un serveur situé sur le réseau. Il peut très bien être déporté sur internet.&lt;br /&gt;
Par exemple grâce aux services en ligne http://redis4you.com/ et http://redistogo.com/.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Grâce à ce dernier point, on peut très bien imaginer les systèmes de traitement répartis sur plusieurs machines aux quatre coins de la terre sur plusieurs réseaux.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Ci-dessous, le code intégrant les capacités de distribution et de parallélisassions sur plusieurs machines.&lt;br /&gt;
Bien entendu, ce n’est pas un code final.&lt;br /&gt;
Il est nécessaire de mieux gérer les logs, les paramètres, la mémoire et mériterait un peu de refactoring :)&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
Pour importer les flux:
ruby feedschecker_cluster.rb -i ~/fichier.opml
&lt;/p&gt;
&lt;p&gt;
Pour connaitre la taille de la pile:
ruby feedschecker_cluster.rb -s
&lt;/p&gt;
&lt;p&gt;
Pour lancer un Worker sur la pile en cours:
ruby feedschecker_cluster.rb -w
&lt;br/&gt;
il bien entendu possible de lancer plusieurs worker sur la même machine.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;logger&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rss&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;nokogiri&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;redis&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FeedsEngine&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NotImplemented&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;StandardEngine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FeedzirraEngine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;feedzirra&amp;#39;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Process url &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Feedzirra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch_and_parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Url processed: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;404&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Error 404&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Entry found: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; entries in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Warning: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardEngine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Process url &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Url processed: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;rss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RSS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;rss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Entry found: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; entries in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Warning: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OpmlParser&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;urls&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;OpmlImporter open file: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@filename&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;outlines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nokogiri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;outline&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;outlines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;xmlurl&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
          &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;OpmlImpoter add url: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; 

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;OpmlImporter error: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Worker&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;QUEUE_SCHEME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;feedschecker:queue&amp;#39;&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;push_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpush&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;QUEUE_SCHEME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quit&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;queue_size&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;QUEUE_SCHEME&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quit&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;StandardEngine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;

    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;

    &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;

    &lt;span class=&quot;vi&quot;&gt;@engine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;work!&lt;/span&gt;

    &lt;span class=&quot;vi&quot;&gt;@redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quit&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Close redis connexion&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pop_feed_url&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Worker pop url...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;brpop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;QUEUE_SCHEME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;work!&lt;/span&gt;
    &lt;span class=&quot;kp&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pop_feed_url&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Worker process url: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Worker.work! error: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cli&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;info&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;use ./feedschecker.rb OPML_FILENAME LOG_LEVEL&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;info&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;info&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;WARN&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;warning&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ERROR&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log_level_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downcase&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./bad_feeds.txt&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FeedsEngine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;no&quot;&gt;OpmlParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opml_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SignalException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ERROR: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bad_feeds_logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Cli.new ARGV[0], ARGV[1]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-i&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;OpmlParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Push url: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-s&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queue_size&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; entries in queue&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-w&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;work!&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2012/05/30/Ruby-Redis-scalabilite.html</link>
			</item>
		
			<item>
				<title>Quelques fonctions Ruby sur les Array</title>
				<description>&lt;p&gt;
Initialement Ruby propose de nombreuses solutions pour manipuler des données.
J&amp;#8217;ai regroupé ci-desous quelques fonctions très utiles et parfois peu connues.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# --- Définition des Array&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;array1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 1 - row 1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 1 - row 2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 1 - row 3&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;array2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 2 - row 1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 2 - row 2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 2 - row 3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;&amp;#39;Array 2 - row 4&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# --- méthode ZIP. Permet de parcourir en même temps deux Array&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;array1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row_array1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row_array2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row_array1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row_array2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# --- Ce qui permet de calculer rapidement la distance euclidienne de deux vecteurs&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;euclidean_distance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;vector1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;component&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;component&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;vector1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;vector2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;euclidean_distance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# --- Permet de réaliser des fenêtres/groupes de données&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;array1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each_slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# --- Même chose mais avec des duplication de données.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;array1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each_cons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2012/05/09/ruby-array.html</link>
			</item>
		
			<item>
				<title>Utilisation de Redis avec Ruby</title>
				<description>&lt;p&gt;
&lt;p&gt;Il y a plusieurs années lorsqu’il était question de faire de la persistance de données au sein d’une architecture logiciel, les développeurs avaient principalement recours aux bases de données &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt;. On parlait de &lt;span class=&quot;caps&quot;&gt;SGDB&lt;/span&gt;.&lt;br /&gt;
Celles-ci apportaient plus de richesse que les fichiers plats, notamment en termes de concurrences, réplications, transactions, etc.&lt;br /&gt;
L’approche &lt;span class=&quot;caps&quot;&gt;ACID&lt;/span&gt; était au centre de ces stratégies.&lt;br /&gt;
Aussi, différents acteurs étaient présents. Ils garantissaient aux utilisateurs des niveaux d’exigences importants particulièrement grâce aux supports techniques (Oracle, SQLServer, etc.). Le marché était très mature et proposait des compétences de haut niveau. Puis des bases de données Open Source, MySQL, Postgresql ont été acceptées au même titre que les solutions propriétaires. Le marché de l’administration s’est peu à peu ouvert aux développeurs, voir aux non informaticiens avec notamment Access.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Depuis maintenant trois ou quatre ans, les bases nommées NoSQL sont arrivées sur un marché relativement fermé aux innovations. En effet, les approches NoSQL sont différentes : les architectures de données notamment sur les aspects que l’on retrouve au sein des « applications sociales » n’imposent pas nécessairement la mise en place de &lt;span class=&quot;caps&quot;&gt;SGDB&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; classique. Certains types de données peuvent être sauvées sous forme de documents ou de graph.&lt;br /&gt;
Sur ce point, les puristes diront que c’est un sacrilège de ne pas respecter l’atomicité des données. Mais si les performances peuvent être sauvées, on peut dire que c’est un mal pour un bien.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Je passe sur le phénomène des Big Data qui en soit n’apporte rien de nouveau.&lt;br /&gt;
A mon sens,  il s’agit clairement d’un recyclage de discours commerciaux pour vendre plus ce qu’on fait depuis longtemps. La volumétrie de données a certes augmentée mais uniquement dans certains secteurs, comme la téléphonie, les média sociaux. Mais ils ont des outils, des techniques et des approches spécifiques en mesure de faire face aux grosses volumétries.&lt;br /&gt;
Pour 95% des entreprises qui souhaitent données de l’intelligence à leurs données il n’est pas nécessaire de faire appel aux Big Data.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Puis, il y a aussi les systèmes à base de Clés/Valeurs, notamment Redis que j’affectionne particulièrement depuis de nombreux mois.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans un logiciel, les données sont stockées dans des tableaux, matrices, Hash, Set…&lt;br /&gt;
Redis repose sur cette une approche qui est vraiment complémentaire. En effet, Redis permet de partager ce type de données entre différents systèmes logiques (comprendre différents logiciels).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Ceci à plusieurs avantages. D’une part les données sont envoyées sur un serveur (redis) en mesure de gérer de façon autonome ses réplications. Donc d’une certaine manière résister aux pannes. Les données sont centralisées sur une architecture n tiers.&lt;br /&gt;
D’autre part, les traitements peuvent être répartis sur plusieurs autres machines autonomes et dédiés. Ce qui a pour conséquence de favoriser la scalabilité horizontale. On peut imaginer des machines spécialisées dans des traitements spécifiques en mesure de venir chercher/échanger les données par l’intermédiaire des serveurs Redis. Si le nombre de données augmente, nous n’avons plus qu’à augmenter le nombre de machines.&lt;br /&gt;
Initialement Redis est véritablement optimisé pour l’échange de données principalement temporaires et volatiles. Inutile donc de défendre Redis pour gérer des transactions bancaires :)&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans ce contexte, Redis est souvent utilisé pour gérer les sessions http entre plusieurs serveurs web.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;De mon coté, j’utilise Redis pour faire du traitement mathématique/statistiques de données. Notamment en ce qui concerne du data mining et text mining.&lt;br /&gt;
Les données initiales sont stockées, soient dans des bases &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; (MySQL ou Postgresql), soient dans des bases NoSQL(mongodb).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Des Workers, c’est à dire des processus autonomes répartis entre plusieurs machines viennent récupérer les données initiales puis appliquent des calculs et stockent les résultats dans une architecture Redis. D’autres Workers, viennent récupérer ces résultats, effectuent leurs traitements puis échangent/sauvent leurs résultats grâce à Rédis.&lt;br /&gt;
Ceci permet partager très rapidement des Hash &amp;amp; Sets, ainsi que des fils d’attentes (Queues).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dès lors, en fonction des enjeux opérationnels, je peux très rapidement répartir la charge de mes workers entre les actions à effectuer.&lt;br /&gt;
Certaines machines sont optimisées pour de la communications réseaux, d’autres pour les calculs. Il suffit d’augmenter ou diminuer le nombre de processus par machines pour gérer les performances.&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Que propose Redis ?&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;Comme je l’ai expliqué plus haut, Redis permet de stocker des données sur un serveur et de les partager avec différents clients.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Chaque donnée est associée à une clé qui est une chaine de caractères. Différentes algorithmes permettent de parser et d’indexer ces éléments. Je vous laisse rejoindre Google pour en savoir plus.&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Stockage Simple avec des clés de type Strings&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Avec Ruby, pour stocker une donnée de ce type j’utilise deux lignes de code. Une pour la connexion, une pour l’affectation.&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;My value !&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;p&gt;Redis stock ces données en « binary safe ». Ces clés peuvent contenir différents types de données. Des chaines de caractères, des entiers, du json, du binaire, notamment du &lt;span class=&quot;caps&quot;&gt;JPEG&lt;/span&gt;, ou des objets sérialisé.&lt;br /&gt;
Cependant, la valeur de chaque clé est limitée à 500Mo. Ce qui laisse de la place :)&lt;br /&gt;
Il est possible d’utiliser différentes opérations sur chaque clé : affectation (set), lecture (get), incrémentations atomiques (incr, decr…), ajout (append).&lt;br /&gt;
Chaque donnée peut aussi être stockée grâce à des namespaces. Un peu comme une url au moyen de séparateurs ( :, /). Ceci permet d’appliquer des patterns de reconnaissance pour l’extraction.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Un autre élément intéressant est qu’il est possible d&amp;#8217;attribuer des dates d’expiration aux données (&lt;span class=&quot;caps&quot;&gt;TTL&lt;/span&gt;) qui vont mourir toutes seules.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Un peu de code ;)&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- connexion&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- ajout, identification, récupération, édition, suppression&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;my value&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mykey = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rename&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;macle&amp;#39;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# use RENAMENX: only if the new key does not exist&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;macle&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;macle&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- uitilisation des namespaces&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylists:mykey1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;my value 1&amp;#39;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# use : or /&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylists:mykey2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;my value 2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylists:mykey1&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylists:mykey2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mylists:*&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- plus loin avec les clés de type String&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;My value&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39; is small&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyClass&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MyClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mydump&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Marshal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Marshal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mydump&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;incr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;incrby&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# utiliser&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   setnx -&amp;gt; set the value of a key, only if the key does not exist&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   strln -&amp;gt; get the length of the value stored in a key&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;abcdef&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getrange&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# set the string value of a key and return its old value&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getset&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;zzz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;value1&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;value2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;value3&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# or use:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mset&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;v1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;v2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;v3&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# use MSETNX: Set multiple keys to multiple values, only if none of the keys exist&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;key3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- expiration temporelle de données&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;my value&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expire&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# in seconds&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ttl: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mykey expired !&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;mykey = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# or use:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   setex: Set the value and expiration in milliseconds of a key&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- persistence des données expirées&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;my value&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ttl: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expire&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ttl: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ttl: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;persist&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;ttl: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ttl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;mykey&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Les Sets&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Les Sets sont des collections d’objets non ordonnés. Pour faire simple, il est possible d’ajouter des lignes de données à un objet Set.&lt;br /&gt;
L’avantage est que chaque élément est unique. En exploitant la méthode &lt;span class=&quot;caps&quot;&gt;SADD&lt;/span&gt;, il est donc inutile de vérifier si les données existent ou non avant l’insertion.&lt;br /&gt;
Clairement les Sets sont utiles pour ranger des listes de données par exemple des liens, résultats, etc.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Redis propose nativement différents opérateurs comme &lt;span class=&quot;caps&quot;&gt;UNION&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;INTERSECTION&lt;/span&gt;, etc. La taille maximum d’un Set est d’un peu plus de 4 milliards d’entrées (4 294 967 295).&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Les Listes&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Redis propose aussi de socker des listes de données. Celles-ci s’apparente plus à des systèmes de Queue/Stack. C’est à dire des zones de données dans lesquelles on empile et dépile hiérarchiquement des données. On peut utiliser les opérateurs &lt;span class=&quot;caps&quot;&gt;PUSH&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;POP&lt;/span&gt;, etc.&lt;br /&gt;
Cette approche est très puissante pour réaliser des systèmes de taches à accomplir au moyen d’ordres partagés entre différents systèmes logiques.&lt;br /&gt;
Les listes permettent de créer des modèle de timelines pour des réseaux sociaux : on empile chaque données et on détruit régulièrement les données périmées.&lt;br /&gt;
Aussi exemple, le gem reuby Resque utilise ces fonctionnalités &lt;span class=&quot;caps&quot;&gt;PUSH&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;POP&lt;/span&gt;.&lt;br /&gt;
La taille maximum d’une liste est d’un peu plus de 4 milliards d’entrées (4 294 967 295).&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;---- gestion des Lists: queue, stack, etc.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# push data&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpush&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpush&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bbb&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpush&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ccc&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpush&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpush&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;eee&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
 
&lt;span class=&quot;c1&quot;&gt;# pop data&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lpop&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rpop&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mylist&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Les Hashes&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Les hash permettent d’aller plus loin dans la persistance de données en proposant des objets évolués. &lt;br /&gt;
Cette approche est très utile, par exemple pour stocker des profils de données ayant plusieurs champs. Par exemple des utilisateurs avec prénom, nom, email, mot de passe, age, etc.&lt;br /&gt;
Tous les champs sont stockés dans un Hash User.&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--- gestion des Hash&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hset&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:aaa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hset&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:bbb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;456&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# or hsetnx: Set the value of a hash field, only if the field does not exist&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:aaa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hget&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:aaa&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:bbb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hget&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:bbb&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:aaa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:bbb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hlen&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hgetall&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;aaa&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bbb&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hkeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hvals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;myhash&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Les Sorted Sets&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Les Sorted Sets sont très similaires aux Sets. Redis permet de les ordonner du stockage de ce type d’objets.&lt;br /&gt;
Toutefois, comme tous les algo. de ce type le temps d’accès à ce type d’objet est proportionnel au logarithme du nombre des éléments. En gros, plus y a d’éléments, plus ca rame…&lt;br /&gt;
S’il n’est pas nécessaire d’ordonner les données, rien ne sert donc d’exploiter ce type d’objet.&lt;/p&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/05/04/redis-ruby-utilisation.html</link>
			</item>
		
			<item>
				<title>Sql to Mongodb</title>
				<description>&lt;p&gt;
Il y a quelques jours, je suis tombé sur une carte présentant la logique permettant de passer
de &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; à MongoDB, notamment en exploitant MapReduce.
&lt;/p&gt;
&lt;p&gt;
Je trouve qu&amp;#8217;elle est bien faite. Par contre, impossible de me souvenir de sa source&amp;#8230;
&lt;/p&gt;
&lt;p&gt;
[Edit du 17 mai 2012 &amp;#8211; Merci à Crazy :)]
La Source est &lt;a href=&quot;http://nosql.mypopescu.com/post/392418792/translate-sql-to-mongodb-mapreduce&quot;&gt;http://nosql.mypopescu.com/post/392418792/translate-sql-to-mongodb-mapreduce&lt;/a&gt;
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;a href=&quot;/images/sql-to-mongodb.jpg&quot;&gt;&lt;img src=&quot;/images/sql-to-mongodb.jpg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/04/13/sql-to-mongodb.html</link>
			</item>
		
			<item>
				<title>Une histoire d'espaces insécables</title>
				<description>&lt;p&gt;
En utilisant la command grep, principalement avec un pipe sur la sortie de &amp;#8220;ps aux&amp;#8221;,
il m&amp;#8217;est (trop?) souvent arrivé d&amp;#8217;avoir une erreur de type:&lt;br/&gt;
command not found:  grep
&lt;br/&gt;Je n&amp;#8217;ai jamais vraiment trouvé de réponse précise à ce problème.
&lt;/p&gt;
&lt;p&gt;
Il s&amp;#8217;agit en fait d&amp;#8217;une histoire d&amp;#8217;espace insécable. Les espaces
insécables sont des caractères invisibles empéchant le retour à la ligne.
Par exemple en &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;, il s&amp;#8217;agit de &amp;nbsp;
&lt;br/&gt;
Ces caractères se déclenchent grâce à une combinaison des touches alt-space.
&lt;br/&gt;D&amp;#8217;où le problème avec le pipe | lorsque l&amp;#8217;on tape trop rapidement sur son clavier.
&lt;/p&gt;
&lt;p&gt;
Pour en savoir plus, il y a l&amp;#8217;article de af83:
&lt;a href=&quot;http://dev.af83.com/2012/03/20/les-espaces-insecables-pour-les-codeurs.html&quot;&gt;http://dev.af83.com/2012/03/20/les-espaces-insecables-pour-les-codeurs.html&lt;/a&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/03/21/espaces-insecables.html</link>
			</item>
		
			<item>
				<title>Deux vulnérabilités dans ImageMagick corrigées</title>
				<description>&lt;p&gt;
Deux vulnérabilités dans ImageMagick viennent d&amp;#8217;être corrigées. Cette librairie est très souvent utilisées coté serveur pour redimensionner et convertir des images après un upload.
Le menace est dangereuse dans la mesure où elle permet l&amp;#8217;exécution de code arbitraire à distance et le déni de service.
Les versions affectées sont ImageMagick antérieures à 6.7.5.3.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/03/08/vulnerabilite-image-magick.html</link>
			</item>
		
			<item>
				<title>Clés SSH sur Github</title>
				<description>&lt;p&gt;
Dans mon précédent billet j&amp;#8217;évoquais la faille de sécurité découverte dans Rails.
&lt;/p&gt;
&lt;p&gt;
Dans le même temps, Github informe ses utilisateurs d&amp;#8217;une vulnérabilité découverte. Elle aurait permis à un l&amp;#8217;attaquant d&amp;#8217;accéder aux clés &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;.&lt;br/&gt;
Il est donc conseillé de les modifier.
&lt;/p&gt;
&lt;p&gt;
Message de Github:
&lt;i&gt;A security vulnerability was recently discovered that made it possible for an attacker to add new &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; keys to arbitrary GitHub user accounts. This would have provided an attacker with clone/pull access to repositories with read permissions, and clone/pull/push access to repositories with write permissions. As of 5:53 PM &lt;span class=&quot;caps&quot;&gt;UTC&lt;/span&gt; on Sunday, March 4th the vulnerability no longer exists.&lt;/i&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/03/08/ssh-github.html</link>
			</item>
		
			<item>
				<title>Vulnérabilité dans Ruby on Rails</title>
				<description>&lt;p&gt;
Le Certa/Anssi, au travers de sa cellule de veille, rapporte deux vulnérabilités dans Ruby On Rails.
Les versions 3.0.x, 3.1.x, 3.2.x sont affectées. Elles concernent l&amp;#8217;injection de code à distance,
principalement au niveau des méthodes SafeBuffer et &amp;#8220;select&amp;#8221; qui ne sont pas filtrées manuellement.
&lt;a href=&quot;http://www.certa.ssi.gouv.fr/site/CERTA-2012-AVI-113/CERTA-2012-AVI-113.html&quot;&gt;Voici la note&lt;/a&gt;.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/03/05/vulnerabilite-ruby-on-rails.html</link>
			</item>
		
			<item>
				<title>Read Now de retour</title>
				<description>&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/readlater.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Il y a quelques semaines j&amp;#8217;avais testé une petite application nommée Read Now.&lt;br /&gt;
	Celle-ci permet d&amp;#8217;accéder à des données postées sur Read It Later.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Malheureusement, Read Now avait été retirée sans aucune raison de l&amp;#8217;AppStore. Depuis quelques heures elle vient d&amp;#8217;être remise au téléchargement sous le nom: &lt;a href=&quot;http://itunes.apple.com/fr/app/read-later/id409349978?mt=12&quot; rel=&quot;nofollow&quot;&gt;Read Later&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/03/02/read-it-later.html</link>
			</item>
		
			<item>
				<title>Quelques tuto videos Ruby</title>
				<description>&lt;p&gt;
Voici un lien vers quelques vidéos présentant Ruby:&lt;br/&gt;
&lt;a href=&quot;http://www.youtube.com/playlist?list=PL1512BD72E7C9FFCA&amp;feature=plcp&quot; rel=&quot;nofollow&quot;&gt;Vidéos Ruby&lt;/a&gt;.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/rails2.png&quot;/&gt;&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/03/01/videos-tuto-ruby.html</link>
			</item>
		
			<item>
				<title>De l’utilité des tests unitaires dans la qualité logicielle</title>
				<description>&lt;p&gt;
&lt;p&gt;Ce billet fait en quelque sorte suite au précédent présentant les techniques d’utilisation de logger. En effet, j’évoquai que, malheureusement, beaucoup (trop ?) de développeurs tracent et debug leurs codes avec une utilisation excessive de « puts », « printf ».&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Je pense que lors du développement d’un produit il est très important d’assurer, dès le début, ses travaux au moyen de petits investissements.&lt;br /&gt;
Ceci permet de garder un code évolutif et de réduire considérablement la dette technique.&lt;/p&gt;
&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Pour optimiser la correction des futures anomalies il est important de déployer des tests unitaires.  Pour faire simple on peut dire que le principe des tests est d’instancier des classes en les considérant comme des boites noires puis en leur injectant des données. Enfin, on regarde en sortie si ces données correspondent à nos attentes.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Cette façon de faire a aussi l’avantage de forcer à développer par « boites ».&lt;br /&gt;
C’est à dire qu’il faut user et d’abuser de la &lt;span class=&quot;caps&quot;&gt;POO&lt;/span&gt; en réduisant le code et en l’enfermant dans des modules, composants et classes. On obtient généralement des sources très structurées et transpirant de maturité (d’où l’utilisation des design pattern – mais j’y reviendrai).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;On rencontre différentes approches de tests : tests unitaires, fonctionnels, d’intégration, de performances, etc. Chacune de ces approches se complètent. Certaines sont très utiles avec Ruby On Rails.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Avec Ruby, il est vraiment très rapide de mettre en place des tests unitaires. Tout est concentré dans le module « test ».&lt;br /&gt;
Pour exposer cette simplicité on peut créer un fichier unique contenant l’ensemble des sources. La partie logique et celle dédiées aux tests.&lt;br /&gt;
Il est impératif de comprendre que d’ordinaire il faut dissocier le code logique de des tests. En général, on retrouve les tests dans un répertoire de l’application nommé ‘test’.&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#encoding: utf-8&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# code logique qui va être testé&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;MonModule&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MaClasse&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ma_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ma_seconde_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# - - -&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# code des tests unitaires&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test/unit&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# généralement on prend le Nom de la classe à tester suivi de &amp;#39;Test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# cette classe hérite de Testt::Unit::TestCase&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MaClasseTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TestCase&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;# la méthode &amp;#39;setup&amp;#39; est appelée avant chaque test&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# on peut donc stoker des variables qui seront utilisées lors de tous les tests&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@ma_classe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MonModule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# on prend le nom de la méthode à tester précédé de &amp;#39;test_&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_ma_methode&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@ma_classe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ma_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# on test avec des &amp;#39;asserts&amp;#39;: assert_equal, assert_not_nil, assert_raise...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_ma_seconde_methode&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# on instancie la classe qu&amp;#39;on veut tester&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ainsi que tous les autres composant nécessaires&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ma_classe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MonModule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ma_classe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ma_seconde_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2012/02/28/test-unit-ruby-rails.html</link>
			</item>
		
			<item>
				<title>Puts vs Logger en Ruby</title>
				<description>&lt;p&gt;
&lt;p&gt;Lors de l’apprentissage d’un langage de développement, tout développeur réalise le traditionnel « Hello World !». Le programmeur se centre sur l’utilisation du vocabulaire propre au langage étudié ainsi que sur ses spécifications lui permettant de mettre en place des algorithmes, d’appréhender la conception de classes et autres mécanismes.&lt;br /&gt;
&lt;br/&gt;Par exemple en C, cette phase permet d’utiliser l’une des méthodes les plus connues: « printf ».&lt;br /&gt;
&lt;br/&gt;En ruby, on retrouve la méthode « puts ».&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Lorsque le développeur réalise ses premiers programmes, toute cette collection de fonctions est utilisée pour sortir de l’information, généralement dans une console.&lt;br /&gt;
Malheureusement, ces méthodes servent souvent, peut être par habitude, à débugger et tracer un programme.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Or, en ruby, il existe la classe Logger en mesure de rendre le travail du développeur beaucoup plus simple surtout lorsque son programme est mis en production.&lt;br /&gt;
  &lt;br/&gt;Cette classe permet par exemple d&amp;#8217;exploiter les différentes sorties: &lt;span class=&quot;caps&quot;&gt;STDOUT&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;STERR&lt;/span&gt;, notamment par les sorties console avec &amp;#8220;./prg &amp;gt; out 2&amp;gt; err&amp;#8221;.&lt;br /&gt;
L’effort pour employer cette classe est vraiment minime.&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Utilisation de Logger&lt;/h2&gt;
&lt;p&gt;Voici le premier code:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;logger&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;WARN&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Début écriture des logs&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Info message...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Warning message...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Error message...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fatal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Fatal message...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Fin écriture des logs&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Ce code est très simple: après le chargement du module Logger, on créé l&amp;#8217;objet en question
avec le paramètre &lt;span class=&quot;caps&quot;&gt;STDOUT&lt;/span&gt;. Celui-ci indique que les écritures des logs vont se faire sur la sortie standard (cad la console). Ce qui équivaut à faire un &amp;#8220;puts&amp;#8221;.
&lt;/p&gt;
&lt;p&gt;
Puis, on affecte un niveau de traitement des logs. Dans notre cas, toutes les logs supérieures ou égales à &lt;span class=&quot;caps&quot;&gt;WARN&lt;/span&gt; seront écrites.
&lt;br/&gt;Ceci sert principalement lors de la release d&amp;#8217;un programme. On affectera ce niveau à Error ou Fatal pour sortir le minimum d&amp;#8217;informations qui seraient utiles.
&lt;/p&gt;
&lt;p&gt;La suite est très simple. Puis on ferme le logger.&lt;/p&gt;
&lt;p&gt;
L&amp;#8217;avantage de cette approche est double. D&amp;#8217;une part on peut très facilement maitriser le niveau d&amp;#8217;information qui va sortir du programme. Celui-ci ne sera pas le même suivant qu&amp;#8217;on l&amp;#8217;éxécute de façon classique ou en mode verbose/dev.
D&amp;#8217;autre part, on peut exploiter le potentiel des sorties &lt;span class=&quot;caps&quot;&gt;STDOUT&lt;/span&gt; et &lt;span class=&quot;caps&quot;&gt;STDERR&lt;/span&gt;.
&lt;br/&gt;
En remplaçant &lt;span class=&quot;caps&quot;&gt;STDOUT&lt;/span&gt; par &lt;span class=&quot;caps&quot;&gt;STDERR&lt;/span&gt;, vous pourrez exécuter le programme avec les traditionnels paramètres &amp;#8220;&amp;gt;&amp;#8230;&amp;#8221; &amp;#8220;2&amp;gt;..&amp;#8221; &amp;#8220;&amp;gt;&amp;gt;..&amp;#8221;:&lt;br/&gt;
./prog 2&amp;gt; err
&lt;br/&gt;
Les logs seront exportées vers le fichier &amp;#8220;err&amp;#8221; alors que tout ce qui concerne la communication avec l&amp;#8217;utilisateur sera sur la console.
&lt;/p&gt;
&lt;h3&gt;Utiliser un fichier de logs&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;logs_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./logs&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logs_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Utiliser SQLite3&lt;/h3&gt;
&lt;p&gt;
&lt;span class=&quot;caps&quot;&gt;STDOUT&lt;/span&gt; &amp;amp; &lt;span class=&quot;caps&quot;&gt;STDERR&lt;/span&gt; sont des LoggerDevice. Ils implémentent deux méthodes: &amp;#8220;write(message)&amp;#8221; et &amp;#8220;close&amp;#8221;.
&lt;br/&gt;On peut donc aussi très facilement créer une nouvelle classe implémentant ces deux méthodes pour par exemple écrire les données dans une base de données.&lt;br/&gt;
Avec une base Sqlite3, ca donnerait ceci, par exemple:
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SQLite3Device&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;sqlite3&amp;#39;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./logs.sqlite&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@conn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SQLite3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_schema_if_necessary&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;insert_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Open logs&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;insert_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;close&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;insert_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Close logs&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;insert_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;INSERT INTO logs VALUES(&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;);&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_schema_if_necessary&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;CREATE TABLE IF NOT EXISTS logs (message BLOB, created_at DATETIME);&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SQLite3Device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Rotation des logs&lt;/h3&gt;
&lt;p&gt;
Il est très utile de noter que Logger possède des fonctionnalités en mesure d&amp;#8217;effectuer des rotation de logs en fonction d&amp;#8217;une durée ou d&amp;#8217;une taille.&lt;br/&gt;
Pour en savoir plus la &lt;a href=&quot;http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html&quot;&gt;doc est très bien faite&lt;/a&gt;.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/02/25/puts-vs-logger.html</link>
			</item>
		
			<item>
				<title>Quelques projets utilisant Ruby On Rails</title>
				<description>&lt;p&gt;
Un billet très court pour parler du top 25 des projets web exploitant Ruby On Rails:
&lt;br/&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.svitla.com/blog/top-25-ruby-on-rails-websites-2011/&quot;&gt;Le top 25 des sites web utilisant Ruby On Rails&lt;/a&gt;.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2012/01/28/sites-utilisant-ruby-on-rails.html</link>
			</item>
		
			<item>
				<title>Créer un Gem Ruby en 2 minutes</title>
				<description>&lt;p&gt;Construire des Gems Ruby permet de faciliter le partage et la diffusion de codes source. Soit au sein de l&amp;#8217;équipe de développement, soit au sein d&amp;#8217;un éco-système Open Source. Par exemple: Github.&lt;/p&gt;
&lt;p&gt;Malgré les apparances, il est très facile d&amp;#8217;organiser son code en conséquence.&lt;/p&gt;
&lt;p&gt;Pour expliquer la démarche, j&amp;#8217;ai choisi un exemple très simple: on va étendre la class Integer afin d&amp;#8217;ajouter une méthode &amp;#8220;add&amp;#8221; permettant d&amp;#8217;ajouter un nombre.&lt;/p&gt;
&lt;h2&gt;L&amp;#8217;architecture du programme&lt;/h2&gt;
&lt;p&gt;
Notre gem va s&amp;#8217;appeler &amp;#8220;my_lib&amp;#8221;. Il faut donc créer un répertoire /my_lib, puis /my_lib/lib. &amp;#8220;/lib&amp;#8221; contiendra le code de notre programme. Dans notre cas, celui-ci nommé par un fichier /my_lib/lib/my_lib.rb
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Il faut créer le fichier décrivant les spec du gem. C&amp;#8217;est à dire: my_lib.gemspec&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Gem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Specification&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;my_lib&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;0.0.1&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;2011-12-28&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Integer Extend&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;The library opens up the Integer class and adds a method &amp;quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;, which returns an addition&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;authors&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Sam&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sam@domain.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;homepage&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://pagedegeek.com&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;lib/my_lib.rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Construire, installer et diffuser le Gem&lt;/h2&gt;
&lt;p&gt;L&amp;#8217;opération de construction du Gem se fait au moyen de la commande suivante:&lt;br/&gt;gem build my_lib.gemspec&lt;/p&gt;
&lt;p&gt;L&amp;#8217;ensemble des sources du Gem sont concentrées dans le fichier nouvellement créé: my_lib-0.0.1.gem&lt;/p&gt;
&lt;p&gt;Il est donc possible de diffuser ce fichier à d&amp;#8217;autres dévelppeurs.&lt;/p&gt;
&lt;p&gt;Pour installer ce fichier, on peut utiliser la commande: sudo gem install ./my_lib-0.0.1.gem&lt;/p&gt;
&lt;p&gt;Pour tester:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;my_lib&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2011/12/28/creer-gem-ruby.html</link>
			</item>
		
			<item>
				<title>Design pattern "Template Method" avec Ruby</title>
				<description>&lt;p&gt;
Il y a quelques semaines j&amp;#8217;avais annoncé que je réaliserai quelques billets sur l&amp;#8217;utilisation des desgins pattern avec Ruby :)
&lt;/p&gt;
&lt;p&gt;
Dans ce billet, je vais donc présenter l&amp;#8217;utilité d&amp;#8217;utiliser le design pattern nommé &amp;#8220;Template Method&amp;#8221;.
Celui-ci a pour but de déléguer et d&amp;#8217;encapsuler le code d&amp;#8217;un traitement spécifique dans des classes filles.
&lt;/p&gt;
&lt;p&gt;
J&amp;#8217;ai pris un exemple très simple: dans le cadre d&amp;#8217;un programme, j&amp;#8217;ai besoin de sortir plusieurs informations (output) dans différents formats.
Dans mon cas, j&amp;#8217;ai mis en place en place deux sorties possible: plain text et &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Que ce passerait-il si je devais ajouter une sortie vers un serveur &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; ou vers une base de données ?
&lt;/p&gt;
&lt;p&gt;
Dans ce cadre, je présente deux démarches: la mauvaise méthode qui n&amp;#8217;est pas vraiment maintenable et une méthode plus évoluée appliquant le design pattern Template Method en Ruby.
&lt;/p&gt;
&lt;h2&gt;Mauvaise approche&lt;/h2&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;###### MAUVAIS CODE / NON MAINTENABLE&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Output&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_begin&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_begin&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:html&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;html&amp;gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:text&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;---&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:html&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:text&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:html&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:text&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World !&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World !&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Ce bout de code, qui a le mérite de fonctionner, ne permet pas d&amp;#8217;avoir une évolution rapide.
Si je dois réaliser une sortie vers une base &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt;, je suis obligé de prendre chaque méthode une part une, puis d&amp;#8217;ajouter le traitement d&amp;#8217;un nouveau format.
Cette approche n&amp;#8217;est vraiment pas très élégante.
Ces modifications risques de provoquer de nombreux bugs.
&lt;/p&gt;
&lt;h2&gt;La bonne approche&lt;/h2&gt;
&lt;p&gt;
La bonne approche consiste à réaliser une classe abstraite ayant quelques méthodes à implémenter.
Les classes filles implementeront à leur manière la façon de traiter les sorties.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Output&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_begin&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NotImplementedError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NotImplementedError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NotImplementedError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HtmlOutput&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Output&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_begin&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;html&amp;gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_end&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TextOutput&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Output&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_begin&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;---&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_end&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Output.new.output #génère une exception: la classe n&amp;#39;est pas instanciable.&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;HtmlOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World !&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;TextOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World !&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Cette approche a le mérite de déléguer l&amp;#8217;ensemble des traitements aux classes filles.
Dans le cadre de l&amp;#8217;ajout d&amp;#8217;un format de sortie il est très facile d&amp;#8217;en ajouter un en créant une nouvelle classe fille.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/12/21/ruby-design-pattern-template.html</link>
			</item>
		
			<item>
				<title>Réflexion sur la qualité des sources et la maintenabilité d’un projet</title>
				<description>&lt;p&gt;Cela fait maintenant plusieurs années que je suis amené à auditer du code source.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Le plus souvent, je suis face à un prestataire qui a conçu un outil, généralement un projet web. Celui-ci souhaite résoudre des problématiques d&amp;#8217;évolutions techniques et fonctionnelles.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Autant le dire aussi brutalement, je constate malheureusement trop souvent que les sources tendent simplement vers une certaine forme de médiocrité : soit, le code manque cruel d&amp;#8217;élégance, soit c&amp;#8217;est carrément la conception qui est défaillante. Dans tous les cas les sources sont usées.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Par code source manquant d’élégance, je pense à des fichiers regroupant des centaines de ligne de codes intégrées dans une unique fonction sans aucune notion d’objet. Pour couronner le tout, je retrouve des parties de codes sources totalement en commentaire…&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Je pense aussi à ces projets cloisonnés dans une arborescence douteuse et présentant des fichiers renommés à la vite par des underscores et des &amp;#8216;&amp;#8230;version-avant-2010&amp;#8230;&amp;#8217;.&lt;br /&gt;
Vous avez surement vu d&amp;#8217;autres exemples ?&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Pourquoi écrire du code de qualité ?&lt;/h2&gt;
&lt;p&gt;Pour moi, le développement logiciel ne se résume à taper de la ligne de code.&lt;br /&gt;
Le développement ne se simplifie pas uniquement à des &amp;#8220;règles métiers&amp;#8221; transpirant les désires du client.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Trop souvent, je découvre de nombreuses fonctionnalités implémentées par de longs discours de façon à s&amp;#8217;approcher vaguement des définitions présentées dans le cahier des charges.&lt;br /&gt;
On retrouve dans ce type de code des enchainements de conditions, sous-conditions, suivies de particularités écrites sans précision spécifique.&lt;br /&gt;
Du sale code…&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;On se retrouve avec du code plus proche de l&amp;#8217;assembleur que de concepts de hauts niveaux.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Les opportunités offertes par les concepts orientés objet sont malheureusement sous-exploitées. Je remarque que les développeurs tombent trop souvent dans les facilités.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Mais n&amp;#8217;importe quel non initié répondra que cette approche a le mérite de fonctionner et participe à la réalisation de l&amp;#8217;effet final recherché de l’application.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Malheureusement il se trombe. Ce type de développement nuit gravement à la maintenabilité du code et donc à son évolution.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;La maintenabilité du code d’un projet est le fondement de sa capacité de réagir aux évolutions futures. Pour moi, cela est l&amp;#8217;élément essentiel de l&amp;#8217;investissement fait par le client.&lt;br /&gt;
Je pense que la qualité doit être une réalité enveloppant le projet dans son ensemble et non une simple option.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Lors des phases de conception ne pas mettre en place une architecture logique reposant sur les bonnes pratiques de conception, notamment l’emploi de design patterns, tend inévitablement vers une certaines forme d&amp;#8217;usure du code.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Un code non maintenable réagira difficilement aux évolutions fonctionnelles et aux corrections; ou du moins sans des efforts excessifs.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Si les phases de conception n&amp;#8217;ont pas pris en compte ces notions en ne faisant, par exemple, que retranscrire les précisions fonctionnelles, alors il est fort possible que les sources codées par la suite vont générer des incompréhensions et bugs logiciels&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Qu&amp;#8217;est-ce qu&amp;#8217;un code/projet de qualité ?&lt;/h2&gt;
&lt;p&gt;Techniquement, je pense qu&amp;#8217;un code de qualité est un code dont sa maintenabilité est assurée et simplifiée à l&amp;#8217;extrême. Tous les concepts: &lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;KISS&lt;/span&gt;&amp;#8230;, Desing Patterns, sont là pour nous aider.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Un projet maintenable est réactif face aux changements.&lt;br /&gt;
La maintenabilité du code, ce n&amp;#8217;est pas des règles bêtement apprises, ni des recettes et encore moins des solutions technologiques. La maintenance du code est uniquement une œuvre de réflexion appliquée au moment de la conception.&lt;br /&gt;
La qualité d&amp;#8217;un code maintenable se mesure sur le long terme.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Chaque développeur doit avoir à l&amp;#8217;esprit que l&amp;#8217;essence du code est plus facile à présenter grâce à des notions de haut niveau.&lt;br /&gt;
Je veux dire par là, qu&amp;#8217;il est plus facile de maintenir des objets que de longues fonctions.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Les sources, mais surtout leur conception, doivent dévoiler les différents buts du projet. Au risque de me répéter ceci peut être facilité par l&amp;#8217;orienté objet.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Aussi, je pense que le projet ne doit pas être considéré uniquement sur la base de finalités fonctionnelles.&lt;br /&gt;
Pour le client, seule cette partie compte vraiment.&lt;br /&gt;
Pourtant, le projet est un ensemble d&amp;#8217;enchainements, d&amp;#8217;écrans et de formulaires. C&amp;#8217;est donc au concepteur/développeur de mettre en œuvre les efforts pour accompagner, conseiller et cadrer les demandes, surtout lorsqu’elles sont atypiques.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Encore trop souvent, j&amp;#8217;entends des industriels qui répondent face à des demandes exotiques de la part de leurs clients, des propos du genre: &amp;#8220;mais Monsieur le client, je fais ce que vous voulez!&amp;#8221;. Sans réflexion, on se retrouve avec des usines à gaz fonctionnelles et techniques.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;Le rôle du concepteur est aussi d&amp;#8217;accompagner le client en proposant des solutions qui vont répondre à la fois aux enjeux fonctionnels mais aussi à la maintenabilité technique du projet. Ceci passe par l&amp;#8217;argumentation du refus d&amp;#8217;implémenter tous les désires exotiques. Il est souvent nécessaire de recadrer ce type de demandes.&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Comment coder avec qualité et élégance&lt;/h2&gt;
&lt;p&gt;Il existe plusieurs moyens permettant de mettre en place une logique de qualité.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Concernant l&amp;#8217;édition du code, il est nécessaire d&amp;#8217;avoir des règles précises et partagées par tous. Je pense principalement aux conventions de nommages des variables, class, etc. Mais aussi aux règles d&amp;#8217;encodage, de tabulations, etc.&lt;/li&gt;
  &lt;li&gt;Il peut être nécessaire de mettre en place des doctrines du type : Do not Repeat Yourself &amp;amp; &lt;span class=&quot;caps&quot;&gt;KISS&lt;/span&gt; (Keep It Simple, Stupid). Cette dernière préconise de rechercher la simplicité dans la conception et l&amp;#8217;architecture logique. Dans ce cadre, ne pas hésiter à rassembler des fonctions au sein d&amp;#8217;objets de type &lt;em&gt;&amp;#8220;Façade&amp;#8221;&lt;/em&gt; ou autre.&lt;/li&gt;
  &lt;li&gt;Coder des fonctionnalités indépendantes du projet dans des plugins (des gems pour Ruby par exemple).&lt;/li&gt;
  &lt;li&gt;Ne pas mélanger les codes &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt;. Ne pas faire du contrôle de données dans les vues. Les contrôleurs ne gèrent pas la validation des données non plus ; ni leur présentation. En général une fonction se compose de 5 à 15 lignes max. de lignes. Une fonction ne fait qu&amp;#8217;une et unique chose.&lt;/li&gt;
&lt;li&gt;Maintenir les évolutions du projet au sein d&amp;#8217;un Système de Gestion de Version. Au pif: &lt;span class=&quot;caps&quot;&gt;GIT&lt;/span&gt; !&lt;/li&gt;
&lt;li&gt;Avoir des espaces de développement, test, pré-prod, prod. et ne pas faire de modifications en prod. User de patch.&lt;/li&gt;
&lt;li&gt;Mettre en place des tests unitaires.&lt;/li&gt;
&lt;li&gt;Refactoriser le code de mauvaise qualité. Consolider l&amp;#8217;existant. Dans cette phase, le but recherché n&amp;#8217;est pas de développer de nouvelles fonctionnalités mais de les implémenter de façon élégante et rationnelle.&lt;/li&gt;
&lt;li&gt;Supprimer le code mort. Dans la vie du projet, il existe obligatoirement des parties du code qui sont inutilisée. Autant les supprimer maintenant.&lt;/li&gt;
&lt;li&gt;Mettre en évidence les problèmes de conception et ne pas hésiter à reforger la conception de l&amp;#8217;application.&lt;/li&gt;
&lt;li&gt;Prendre en considération que le code « s’use » !&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/12/20/code-source-qualite.html</link>
			</item>
		
			<item>
				<title>Pagination à la Facebook avec Ruby On Rails</title>
				<description>&lt;p&gt;
J&amp;#8217;avais envie de présenter très rapidement comment mettre en place un système de pagination très simple à la Facebook.
C&amp;#8217;est à dire que le contenu ne se charge plus par page mais par date de création grâce à &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt;.
&lt;/p&gt;
&lt;h2&gt;Le Controller&lt;/h2&gt;
&lt;p&gt;
On va commencer par le controller en exploitant la fonction respond_with() de rails 3 permettant de générer les données en fonction du type souhaité (&lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;, etc.).

&lt;br/&gt;Bien entendu, ce code peut être optimisé avec des scopes, mais je n&amp;#8217;avais pas envie de surcharger cet article.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:json&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:last&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;present?&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;created_at DESC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;created_at &amp;lt; ?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:last&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;created_at DESC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;respond_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;La Vue&lt;/h2&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Listing posts&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-last=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;%= @posts.last.created_at %&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;% @posts.each do |post| %&amp;gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%= post.body %&amp;gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;% end %&amp;gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;javascript:void(0)&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;load_posts&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Le javascript&lt;/h2&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;$(function(){
  $(&amp;#39;.load_posts&amp;#39;).click(function(){
    $.getJSON(&amp;quot;/posts.json?last=&amp;quot; + $(&amp;#39;#posts&amp;#39;).attr(&amp;#39;data-last&amp;#39;), function(data){
      $.each(data, function(k,v){
        $(&amp;#39;#posts&amp;#39;).append(&amp;quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&amp;quot; + v.body + &amp;quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&amp;quot;);
        $(&amp;#39;#posts&amp;#39;).attr(&amp;#39;data-last&amp;#39;, v.created_at);
      });
    });
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Un initializer pour gérer l&amp;#8217;affichage de la date avec &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Par defaut avec json, la conversation d&amp;#8217;une date en chaine de caractère n&amp;#8217;est pas vraiement optimale. Il est donc nécessaire de créer un initializer par exemple config/initializers/times_format_json.rb&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ActiveSupport&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TimeWithZone&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;as_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;%Y-%m-%d %H:%M:%S UTC&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Voilà !&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/12/19/pagination-a-la-facebook.html</link>
			</item>
		
			<item>
				<title>Livres bonnes pratiques programmation orienté objet</title>
				<description>&lt;p&gt;
&lt;p&gt;J’ai rencontré beaucoup de développeurs sachant programmer, ou du moins se servir d&amp;#8217;un langage de programmation. Ces développeurs sont souvent autodidactes sur des technologies particulières.&lt;br /&gt;
Je pense qu’il n’y a rien de mal à ca. Au contraire, il est important de suivre les évolutions techniques.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Toutefois, la conception d’ensemble d’une application ne se résume pas à taper de la ligne de code et à appliquer à la lettre les recommandations d’une documentation.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Je pense que peu de personnes savent bien concevoir l&amp;#8217;architecture logique d&amp;#8217;une application. Par architecture logique, j’entends l’implémentation des concepts métiers de haut niveau.&lt;br /&gt;
De la même manière que la programmation, la conception d’application s’apprend aussi en étudiant ce qui a déjà été fait.&lt;br /&gt;
J’ai donc retenu quelques livres utiles à ceux et celles qui veulent se perfectionner dans cet art.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.amazon.com/Object-Oriented-Analysis-Design-Applications-3rd/dp/020189551X/ref=sr_1_1?ie=UTF8&amp;qid=1324199412&amp;sr=8-1&quot;&gt;Object Oriented Analysis Design Applications&lt;/a&gt;&lt;br /&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324199453&amp;sr=1-1&quot;&gt;Object Oriented Software&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/12/18/livres-bonnes-pratiques-poo.html</link>
			</item>
		
			<item>
				<title>Plugins VIM essentiels avec Ruby & Rails</title>
				<description>&lt;p&gt;
Je le présentais dernièrement dans un billet, j&amp;#8217;ai quitté TextMate pour &lt;a href=&quot;http://www.pagedegeek.com/2011/10/10/retour-aux-sources-textmate-a-vim.html&quot;&gt;passer à &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt;&lt;/a&gt;.
TextMate a gagné la confiance des développeurs grâce à sa capacité de configuration et à ses nombreux raccourcis clavier très productifs.
Beaucoup de développeurs, principalement issus du web, ont fait le choix d&amp;#8217;exploiter un éditeur de code évolué plutôt d&amp;#8217;un &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;. Notamment pour pallier à leur lourdeur.
Je pense que cette tendance s&amp;#8217;est développée grâce aux capacités avancées de personnalisation des éditeurs de code. Par exemple, ils proposent des systèmes de &amp;#8220;Snippet&amp;#8221; qui sont très productives. Celles-ci permettent de générer des parties de code source &amp;#8220;à la volée&amp;#8221;. Je ne parle pas de génération automatique de codes. Simplement la possibilité de générer et d&amp;#8217;automatiser la production de quelques lignes de code souvent répétitives.
Ce système permet, à mon sens, une plus grande maitrise des sources.
&lt;/p&gt;
&lt;h3&gt;Snippet&lt;/h3&gt;
&lt;p&gt;
Vim propose par defaut un système équivalent aux Snippets. Ce sont les &amp;#8220;abbreviations&amp;#8221;.
Par exemple, en saisissant la ligne suivante dans votre .vimrc:
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;  abbr psvm public static void main&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;String&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; args&lt;span class=&quot;o&quot;&gt;){&lt;/span&gt;&amp;lt;CR&amp;gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&amp;lt;esc&amp;gt;0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
vous pourrez, en tapant psvm puis &lt;span class=&quot;caps&quot;&gt;TAB&lt;/span&gt;, générer la ligne de code très connue en C: public(&amp;#8230;).
&lt;/p&gt;
&lt;p&gt;
Toutefois, j&amp;#8217;ai trouvé le plugin SnipMate plus intéressant: &lt;a href=&quot;https://github.com/msanders/snipmate.vim&quot; rel=&quot;nofollow&quot;&gt;Télécharger SnipMate &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt;&lt;/a&gt;.
Celui-ci se compose par default de différentes snippets situées dans .vim/snippets/*.
La documentation est très bien faite. Je ne vais donc pas rentrer dans les détails. Il faut juste noter que les snippets liées à &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; &amp;amp; Ruby sont très productives.
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;NOTE&lt;/span&gt;: Sous MacVim il existe un petit problème: lorsque l&amp;#8217;on sélectionne du texte, une pression sur backspace fait revenir le curseur au delà de la position classique.&lt;br /&gt;
	Pour corriguer ce problème, il suffit de commenter la ligne &amp;#8220;snor &lt;bs&gt; b&lt;bs&gt;&amp;#8221; située dans le fichier .vim/after/plugin/snipMate.vim.&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Auto Close&lt;/h3&gt;
&lt;p&gt;
Par defaut, &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt; ne propose pas la fermeture des symboles: [], (), {}.
J&amp;#8217;ai comblé cette lacune avec le plug-in &amp;#8220;autoclose&amp;#8221; disponible à cette adresse: &lt;a href=&quot;https://github.com/Townk/vim-autoclose&quot; rel=&quot;nofollow&quot;&gt;https://github.com/Townk/vim-autoclose&lt;/a&gt;.
&lt;/p&gt;
&lt;h3&gt;Ouverture des fichiers&lt;/h3&gt;
&lt;p&gt;
&lt;a href=&quot;https://github.com/scrooloose/nerdtree&quot; rel=&quot;nofollow&quot;&gt;NERDTree&lt;/a&gt; permet d&amp;#8217;ouvir un arbre présentant les fichiers du dossier courant.
L&amp;#8217;ouverture de cet arbre peut être mappé. Ainsi en mode visualisation, en tapant F12, l&amp;#8217;arbre s&amp;#8217;affiche ou non. Voici mon .vimrc paramétrant ces éléments:
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;map &amp;lt;F12&amp;gt; :NERDTreeToggle&amp;lt;CR&amp;gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;let g:NERDTreeWinPos = &amp;quot;&lt;/span&gt;right&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;let &lt;/span&gt;g:NERDTreeWinSize&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;33
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Sous TextMate la touche Cmd-T facilite l&amp;#8217;ouverture d&amp;#8217;un fichier recherché.
Le plugin-in &lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=1984&quot;&gt;FuzzyFinder&lt;/a&gt; permet de mettre en place cette fonctionnalité de la même manière.
Notamment la commande &amp;#8220;:FufCoverageFile&amp;#8221;.
J&amp;#8217;ai mappé celle-ci avec la touche F11, ce qui donne dans mon .vimrc:
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;map &amp;lt;F11&amp;gt; :FufCoverageFile&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Lorsqu&amp;#8217;un fichier est selectionné, on peut utiliser différentes combinaisons pour l&amp;#8217;ouvrir:&lt;br/&gt;
- Enter pour ouvrir dans la fenêtre courante&lt;br/&gt;
- CTRL+j pour ouvrir avec un split&lt;br/&gt;
- CTRL+k pour ouvrir avec un vsplit&lt;br/&gt;
- CTRL+k pour ouvrir dans une tab
&lt;/p&gt;
&lt;h3&gt;Editer du code eRuby&lt;/h3&gt;
&lt;p&gt;
Sous Textmate, il est possible de créer automatiquement le code suivant: &amp;#8220;&amp;lt;%=  %&amp;gt;&amp;#8221; au moyen du raccourcis SHIFT+CTRL+&amp;gt;.
Le plugin &lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=1896&quot; rel=&quot;nofollow&quot;&gt;RagTag&lt;/a&gt; permet de réaliser ceci sous &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt; au moyen des touches CTRL+W puis = ou SHIFT+=.
&lt;/p&gt;
&lt;h3&gt;De la couleur&lt;/h3&gt;
&lt;p&gt;
Il existe aussi le thème RailsCasts disponible: &lt;a href=&quot;https://github.com/jpo/vim-railscasts-theme&quot; rel=&quot;nofollow&quot;&gt;RailsCasts adapté à &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt;&lt;/a&gt;. Toutefois, j&amp;#8217;ai préféré utiliser mon propre thème: &lt;a href=&quot;https://github.com/samditbien/parisbynight&quot;&gt;ParisByNight&lt;/a&gt; adapté à Ruby On Rails.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/11/29/vim-plugins.html</link>
			</item>
		
			<item>
				<title>Alternatives à Yahoo Explorer</title>
				<description>&lt;p&gt;
&lt;p&gt;Yahoo Explorer vient de fermer ses portes. Dommage, cet outil était vraiment très pratique pour avoir une vision assez globale des backlinks pointant vers une page spécifique. &lt;br /&gt;
	Ceci est intéressant en &lt;span class=&quot;caps&quot;&gt;SEO&lt;/span&gt; pour en savoir plus sur un domaine particulier (le sien ou dans un environnement concurentiel par exemple).&lt;br /&gt;
	Il existe pas mal d’outils en mesure d’apporter ce type de connaissance. Malheureusement, ils n’ont pas l’avantage de posséder l’index de Yahoo.&lt;br /&gt;
	Je vous propose donc une petite liste d’autres &lt;b&gt;outils alternatifs à Yahoo Explorer&lt;/b&gt;. Il est important de noter ces outils en ligne n’ont pas la puissance de yahoo car ils ne &amp;#8220;crawlent&amp;#8221; malheureusement qu’une petite partie du web.&lt;/p&gt;
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;http://www.opensiteexplorer.org/&lt;/li&gt;
	&lt;li&gt;http://www.analyzebacklinks.com/&lt;/li&gt;
	&lt;li&gt;http://www.bing.com/search?q=&lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;SITE&lt;/span&gt;&amp;amp;go=&amp;amp;qs=bs&amp;amp;form=&lt;span class=&quot;caps&quot;&gt;QBRE&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;http://www.google.fr/search?q=link:&lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;SITE&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;http://www.alexa.com/site/linksin/&lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;SITE&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;http://www.exalead.fr/search/web/results/?q=link:&lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;SITE&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;https://www.majesticseo.com&lt;/li&gt;
	&lt;li&gt;http://www.seoheap.com/backlink-checker/&lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;SITE&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;http://www.backlink-tracker.net/reports/&lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;SITE&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/11/22/alternative-yahoo-explorer.html</link>
			</item>
		
			<item>
				<title>Vulnérabilité dans Ruby On Rails</title>
				<description>&lt;p&gt;
&lt;p&gt;Ruby On Rails comporte une vulnérabilité permettant l&amp;#8217;injection de code à distance.&lt;br /&gt;
	Celle-ci concerne les version 3.0.0 et supérieures, ainsi que les 2.3.x utilisant le module rails_xss.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;La vulnérabilité est présente dans la fonction &amp;#8220;translate&amp;#8221; de Ruby On Rails&lt;/p&gt;
&lt;h4&gt;Sources&lt;/h4&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://weblog.rubyonrails.org/2011/11/18/rails-3-0-11-has-been-released&quot;&gt;http://weblog.rubyonrails.org/2011/11/18/rails-3-0-11-has-been-released&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://weblog.rubyonrails.org/2011/11/18/rails-3-1-2-has-been-released&quot;&gt;http://weblog.rubyonrails.org/2011/11/18/rails-3-1-2-has-been-released&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.certa.ssi.gouv.fr/site/CERTA-2011-AVI-653/CERTA-2011-AVI-653.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CERTA&lt;/span&gt; de l&amp;#8217;ANSSI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/11/21/vulnerabilite-ruby-on-rails.html</link>
			</item>
		
			<item>
				<title>Déployer plusieurs applications Rails 3 sur un serveur Apache 2.2 avec Phusion Passenger</title>
				<description>&lt;p&gt;Tout d&amp;#8217;abord j&amp;#8217;ai préféré déployer httpd en local en recompilant les sources.&lt;br /&gt;
Ceci afin d&amp;#8217;être relativement autonome dans la gestion des dépendances et des modules.&lt;br /&gt;
&lt;br/&gt;
La procédure d&amp;#8217;installation à suivre est classique:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;tar zxvf httpd-2.2.21
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;httpd-2.2.21
./configure --prefix&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Applications/httpd/2.2.21 --enable-so
make
sudo make install
unlink /Applications/httpd/current
ln -s /Applications/httpd/2.2.21 /Applications/httpd/current
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;On peut tester si httpd se lance bien en suivant cette procédure:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /Applications/httpd/current/bin
sudo ./apachectl start
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Déployer Phusion Passenger&lt;/h3&gt;
&lt;p&gt;On commence par installer le gem avec la commande suivante:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;sudo gem install passenger
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Puis on lance l&amp;#8217;opéation de déploiement sur httpd:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;passenger-install-apache2-module --apxs2-path&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Applications/httpd/current/bin/apxs
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;L&amp;#8217;installateur nous demande d&amp;#8217;ajouter les lignes suivantes dans le httpd.conf:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;LoadModule passenger_module /Applications/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
PassengerRoot /Applications/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/passenger-3.0.9
PassengerRuby /Applications/ruby/1.9.3-p0/bin/ruby
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Puis se clôture en proposant une configuration pour une application rails.&lt;br /&gt;
Celle-ci est assez simple. Je vous propose plutôt la mienne qui permet d&amp;#8217;exploiter plusieurs applications rails sur un même serveur httpd.&lt;br /&gt;
Cette configuration est utile dans le cadre d&amp;#8217;applications locales ou sur un serveur de test, voir de petites applications en prod.&lt;/p&gt;
&lt;p&gt;Dans mon contexte, j&amp;#8217;ai créé un répertoire railsapp à la racine de httpd: /Applications/httpd/2.2.21/railsapp/&lt;/p&gt;
&lt;p&gt;En production, de même que le fichier htdocs, il est recommandé de mettre les applications dans /var ou /opt et d&amp;#8217;adapter les droits en conséquence.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;On commence par créer un lien symbolique dans le htdoc d&amp;#8217;apache httpd:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;ln -s /Applications/httpd/2.2.21/railsapp/HelloApp/public/ /Applications/httpd/2.2.21/htdocs/hello
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Il faut bien faire pointer le répertoire &amp;#8220;public&amp;#8221; de l&amp;#8217;application.&lt;/p&gt;
&lt;p&gt;Puis on créé un Virtualhost dans le httpd.conf:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&amp;lt;VirtualHost *:80&amp;gt;
	DocumentRoot /Applications/httpd/current/htdocs/
	&amp;lt;Directory /Applications/httpd/current/htdocs/&amp;gt;
		&lt;span class=&quot;c&quot;&gt;#Order allow,deny&lt;/span&gt;
		Allow from all
  &amp;lt;/Directory&amp;gt;
	
	RailsBaseURI /hello
	RailsEnv production
	
	&amp;lt;Directory /Applications/httpd/current/htdocs/&amp;gt;
		Options -MultiViews
	&amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;RailsBaseURI /hello doit correspondre au lien symbolique que l&amp;#8217;on a créé dans le htdocs. Attention donc à la casse.&lt;br /&gt;
Il est possible de créer d&amp;#8217;autres application en créant simplement d&amp;#8217;autres liens symboliques et les en faisant pointer sur d&amp;#8217;autres RailsBaseURI /&lt;nom-ln-s-app&gt;.&lt;/p&gt;
&lt;p&gt;Avant une mise en production d&amp;#8217;une application Rails 3, il est nécessaire de pré-compiler les assets en éxécutant la commande suivante:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;bundle &lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;rake assets:precompile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Aussi, il ne faut pas oublier de monter votre base de données de production avec:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;rake db:create &lt;span class=&quot;nv&quot;&gt;RAILS_ENV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;production
rake db:migrate &lt;span class=&quot;nv&quot;&gt;RAILS_ENV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Voilà!&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/11/18/deployer-rails-passenger-apache-httpd.html</link>
			</item>
		
			<item>
				<title>Raccourcis SSH</title>
				<description>&lt;p&gt;
&lt;p&gt;Lorsque l&amp;#8217;on gère quelques serveurs &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;, notamment pour ses clients ou ses propres besoins, il est fastidieux de devoir taper à la main à chaque fois l&amp;#8217;url ou l&amp;#8217;IP des serveurs.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Avec &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;, il est possible de créer des raccourcis. Il suffit de créer le fichier de configuration suivant:&lt;br/&gt;
	# vi ~/.ssh/config&lt;br/&gt;
	puis de saisir quelques lignes de configuration.&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;host srv1
  hostname 0.0.0.0
  user developer

host srv2
  hostname 0.0.0.0
  user root
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;p&gt;srvX correspond au nom que l&amp;#8217;on veut donner au raccourcis. On utilisera directement dans un terminal la commande suivante:&lt;br/&gt;
	# ssh srvX&lt;br/&gt;
	0.0.0.0 est l&amp;#8217;IP de la machine. On trouve ensuite le nom d&amp;#8217;utilisateur de connexion &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;.&lt;/p&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/11/16/raccourcis-ssh.html</link>
			</item>
		
			<item>
				<title>Une extension en C pour Ruby</title>
				<description>&lt;p&gt;
Il y a quelques jours j&amp;#8217;ai eu besoin d&amp;#8217;étendre Ruby en réalisant une extension en C.
En effet, mon algo. comportait des calculs mathématiques déjà optimisés en C. J&amp;#8217;ai donc préféré la transformer en librairie et l&amp;#8217;exploiter avec Ruby.
&lt;/p&gt;
&lt;p&gt;
Pour réaliser une extension C en Ruby, c&amp;#8217;est très simple. Pour commencer, il faut le fichier monextension.c et test_monextension.rb.
Le premier fichier correspond au code source. Le second ficher afin d&amp;#8217;exploiter l&amp;#8217;extension.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;./monextension&amp;#39;&lt;/span&gt;

&lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MonExtension&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ma_methode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;c&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;ruby.h&amp;gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;VALUE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MonExtension&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Qnil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Init_mytest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;VALUE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method_ma_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VALUE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Init_monextension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;MonExtension&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rb_define_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;MonExtension&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;rb_define_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MonExtension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;ma_methode&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method_ma_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;VALUE&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method_ma_methode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VALUE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INT2NUM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Pour compiler la librairie, il est possible de générer automatique un make file. Pour se faire, il faut créer le fichier extconf.rb
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mkmf&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ext_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;monextension&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;dir_config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ext_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;create_makefile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ext_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;En l&amp;#8217;exécutant avec un ruby extconf.rb, vous générerez automatique le makefile&lt;/p&gt;
&lt;p&gt;Pour compiler l&amp;#8217;extension, rien de bien compliqué. Vous tapez un &amp;#8220;make&amp;#8221; dans le terminal afin de compiler la librairie.&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/31/extension-c-pour-ruby.html</link>
			</item>
		
			<item>
				<title>Gestion d'un projet innovant</title>
				<description>&lt;p&gt;
&lt;p&gt;Cette note s’adresse avant tout aux entrepreneurs et aux personnes souhaitant mettre en place un projet innovant. Le web regorge de ressources pour décrire un business plan, choisir une architecture technique, etc. Mais, je n’ai pas vraiment trouvé d’informations concernant la gestion de projets innovant, requérant implicitement des efforts de créativité.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Il y a plusieurs mois j’ai été amené à diriger un projet qui n’était pas vraiment conventionnel. Il s&amp;#8217;agissait d&amp;#8217;un projet d’innovation. Ce type de démarche est problématique dans le sens où la créativité doit émerger d’une équipe et non d’une seule personne.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Depuis quelques années, je pense que le terme innovant est malheureusement reprit à toutes les sauces. Dès qu&amp;#8217;un discourt est diffusé afin de présenter un produit, le terme innovant est rapidement associé. Souvent à tord.&lt;br /&gt;
Je pense que beaucoup d&amp;#8217;individus confondent nouveauté et innovation. Créer un projet innovant ne se résume pas à créer un projet nouveau.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Diriger un projet, notamment lorsqu&amp;#8217;il s’agit d&amp;#8217;un projet web, est un processus globalement maitrisé. On réalise des briefings client. Puis un cadrage fonctionnel est effectué au moyen d&amp;#8217;un cahier des charges. On peut mettre en place différentes approches de construction (livraison par lots, en mode agile, etc.).&lt;br /&gt;
Lorsque le porteur de projet sait globalement ce qu&amp;#8217;il veut, là où il veut aller sur le plan fonctionnel, il se repose sur la &lt;span class=&quot;caps&quot;&gt;MOE&lt;/span&gt; pour retranscrire ses attentes dans une dimension technique afin de bâtir son projet.&lt;br /&gt;
Bien sûr, il peut y avoir quelques éléments perturbants, des aléas, des incompréhensions. Mais celles-ci font parties intégrantes de la vie du projet.&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Qu&amp;#8217;en est-il d&amp;#8217;un projet innovant ?&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Par innovant j’entends un projet dont l&amp;#8217;issue finale est incertaine, indéfinie. Tant sur le plan fonctionnel, organisationnel que technique. Un projet dont l&amp;#8217;effet final recherché (&lt;span class=&quot;caps&quot;&gt;EFR&lt;/span&gt;) n&amp;#8217;est pas et ne peut être défini avec précision.&lt;br /&gt;
Il s&amp;#8217;agit d&amp;#8217;une situation où les porteurs de projet ont une idée générale décrivant une carence qu&amp;#8217;ils ont identifiée et souhaitent la combler. Ils souhaitent apporter leur brique à l&amp;#8217;édifice sans trop connaitre celui-ci.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dès lors, quelles ressources mettre en place pour atteindre une étape opérationnelle ? Les méthodes de conduite de projet classiques fonctionnent-elles dans cet environnement ? Peut on se contenter de briefs, de cahiers des charges clairement établis ? Doit-on justifier d’une approche agile ? Comment évoluer entre ordre et chaos créatif ? Comment gérer la créativité et le facteur humain dans ce contexte ?&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Mon expérience ma montré que ce type de projet nécessite de gros efforts. Je ne parle pas uniquement d&amp;#8217;efforts financiers.&lt;br /&gt;
A ce stade, il est malheureusement classique pour un porteur de projet de tomber dans les facilités faisant intervenir uniquement les enjeux techniques. Il est courant de tout faire reposer sur la technicité du projet.&lt;br /&gt;
J&amp;#8217;ai remarqué que les environnements inconnus sont en général considérés par les profanes comme étant capable de répondre à tous les problèmes du projet. La faute peut être aux discours magiques de commerciaux peu scrupuleux; ou peut être au manque de curiosité des équipes se contentant de phrases toutes faites.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;A ce titre, je me souviens d&amp;#8217;avoir entendu que le manque de curiosité était un défaut professionnel. Qu’en pensez-vous ?&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans ce contexte, il est très facile d&amp;#8217;amalgamer des systèmes à des boites noires. Le porteur de projet part du principe que des sortes alchimistes connaissent les méandres de systèmes et sont en mesure, par l&amp;#8217;intermédiaire d&amp;#8217;une technologie ésotérique de transformer n&amp;#8217;importe quel plomb en or.&lt;br /&gt;
Pour le client, toutes les problématiques auront des solutions, sans aucune limite, sans prendre en considération les contraintes, sans concession nécessaires. (De toute façon le client est roi, dit-on ?).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;On peut aussi rencontrer le porteur de projet qui souhaite « challenger » des développeurs comme il le ferait avec ses commerciaux. Or, il ne fait que confirmer son incapacité à ne pas comprendre que les défis techniques ne sont pas en mesure de répondre à des sollicitations par le stress. De plus, il ne prend pas en compte la démotivation des développeurs qui est pourtant une réalité bien réelle. Est-il nécessaire de rappeler qu&amp;#8217;un bon développeur démotivé partira. Dans ce contexte, qu&amp;#8217;en sera-t-il de la perte connaissance du projet ?&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Ces considérations sont malheureusement des erreurs et portes inévitablement le projet innovant vers l&amp;#8217;échec.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Au stade d&amp;#8217;innovation, seul compte le facteur humain!&lt;br /&gt;
L&amp;#8217;accompagnement projet est fondamental. Il faut arriver à repositionner l&amp;#8217;Homme et surtout sa créativité au centre du projet. Le principal défi est la mise en place d’outils permettant de canaliser la créativité issue de l’équipe projet. Il faut impérativement esquiver les caprices du client roi. C’est de toute façon pour son bien.&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Définissons quelques points&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Tout d’abord, le projet étant de nature innovante son objectif final n’est pas défini avec précision. Il peut évoluer en fonction du temps et des informations en présence.&lt;br /&gt;
Il faut donc se concentrer sur ce qui est important au projet.&lt;br /&gt;
Le porteur du projet vous répondra par des enjeux fonctionnels, des réalités économiques et des finalités techniques. Mais avant tous ces éléments, comme j’ai essayé de le décrire plus haut, la motivation des membres projet est un élément critique : sans personnels, pas de créativité, pas de projet. La motivation étant source de créativité. S’il y a bien un élément qui ne peut s’acheter et se maitriser, c’est bien la capacité créative. Vous pourrez recruter des personnes qui ont été créatives dans le passé ; rien n’affirme qu’elles le seront sur votre projet.&lt;br /&gt;
On peut donc s’attarder à identifie au plus tôt ce qui anime les membres du projet, par exemple en exploitant la pyramide de Maslow.&lt;br /&gt;
J’ai envi de reprendre la citation d’Antoine de Saint Exupéry qui résume bien la situation (j’en prendrai d’ailleurs d’autres) : « &lt;i&gt;Si tu veux construire un bateau, ne rassemble pas tes hommes et femmes pour leur donner des ordres, pour expliquer chaque détail, pour leur dire où trouver chaque chose&amp;#8230; Si tu veux construire un navire, fais naître dans le cœur de tes hommes et femmes le désir de la mer. &lt;/i&gt;»&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Rester face à la réalité.&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Il vaut mieux refuser des fonctionnalités trop couteuses en temps ou trop compliquées à ce stade du projet innovant.&lt;br /&gt;
Mettre la pression sur des éléments intenables ou des délais trop court est un risque à ne pas prendre. Cela rassurera tout au plus le cient roi, dictateur qui retrouvera ses repères.&lt;br /&gt;
Ce genre de situation a pour conséquences de créer de fausses attentes, de générer du stress inutile et de fournir une vision altérer des échéances.&lt;br /&gt;
Il faut aussi se rappeler qu’une personne malgré son expérience est très mauvaise pour prévoir.&lt;br /&gt;
J’aime beaucoup ce que dit Antoine de Saint Exupéry dans Terre des Hommes à propos de l’évolution de l’aviation : «&lt;i&gt; Dans quelque domaine que ce soit, la perfection est enfin atteinte non pas lorsqu&amp;#8217;il n&amp;#8217;y a plus rien à ajouter mais lorsqu&amp;#8217;il n&amp;#8217;y a plus rien à enlever &lt;/i&gt;» Antoine de Saint-Exupéry&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Communiquer !&lt;/h3&gt;
&lt;p&gt;Il ne faut pas uniquement communiquer pour rassurer le client ou prendre ses directives d’une chaine hiérarchique. Il faut qu’il y ait un échange d’informations à battons rompus sans distinction de système hiérarchique. Il éviter certaines personnes avides de reconnaissances qui monopoliseront sans état d’âmes les débats et orienteront les échanges dans de mauvaises directions.&lt;br /&gt;
De la même manière, il faut éviter que les personnels hiérarchiques exploitent leur position afin de se rassurer sur leurs capacités managériales.&lt;/p&gt;
&lt;p&gt;Elles doivent plutôt se concentrer sur la capacité à faire émerger chez les personnels des éléments de créativité.&lt;/p&gt;&lt;p&gt;La communication doit être régulière. Idéalement, les membres projet devraient se parler physiquement tous les jours. Leur rôle est de faciliter cette cohésion.&lt;br /&gt;
Si les membres projet sont nombreux, qu’il y a des difficultés de planning pour se réunir, on peut mettre en place des binômes temporaires qui travaillerons sur une semaine ensemble. La semaine suivante après un Retex, on change les binômes. Les idées évoluerons d’elles mêmes.&lt;/p&gt;
&lt;h3&gt;Ecouter !&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;L’écoute au sein d’une réunion créative est très importante, même si ce qui est dit est sans intérêt pour le projet. En coupant un échange ou en cadrant immédiatement un personnel, il se peut qu’elle ressente une frustration à ne pas pouvoir s’exprime par la suite.&lt;br /&gt;
Dans le futur, rien ne permet d’affirmer que cette personne pourrait apporter une solution à une nouvelle problématique. Si elle a été frustrée, il se peut qu’elle s’enferme dans son silence. Il faut se forcer à différer le jugement.&lt;br /&gt;
Toutefois, cette approche est un jeu difficile lorsqu’il s’agit de cadrer un caprice d’un manager.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans le contexte d’un projet innovant, face à une problématique tout le monde peut avoir une solution à proposer. Tout le monde peut proposer sa vérité et ses raisons. Il est très difficile d’avoir raison, d’émettre une vérité absolue par exemple en décrivant une fonctionnalité.&lt;br /&gt;
Il faut faire comprendre que tous les personnels peuvent avoir raison, tout le monde peut se tromper, tout le monde peut changer d’avis. Il est absolument nécessaire de mettre en place une situation où l’intuition de l’un ne pèse pas plus que l’intelligence de l’autre, que l’expérience de l’un n’équivaut pas plus que l’intuition de l’autre et l‘expérience n’évince pas le fantasme d’un autre.&lt;br /&gt;
A ce stade d’un projet d’innovation, il faut éviter les dictatures autoritaires et les décisions figées.&lt;br /&gt;
Si certaines propositions sont trop abstraites, on peut utiliser des paper board pour communiquer. Les autres membres projet pourront « écouter » avec plus de facilité.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Les réunions doivent avoir un centre d’équilibre entre chaos créatif et ordre éclairant. Il faut équilibrer le respect des idées des autres et ses idées. La créativité doit être partagée avec chaque équipier.&lt;br /&gt;
Ces réunions doivent absolument se clôturer sur des idées optimistes. Ces éléments doivent être source de joie. Chaque membre projet doit désirer que quelque chose naisse et émerge de cette réunion. Il faut rester dans le champ des possibles. Le rôle du manager est de transpirer cette joie et de la rendre contagieuse.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Ces réunions créatives sont de véritables processus de recherche d’idée en équipe. Résoudre des problèmes, créer doit être source d’amusement. Même si les personnels sont payés des fortunes, ils doivent s’amuser. Ce n’est pas se contenter d’appliquer des normes et des modèles existants pour solutionner une problématique.&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;Pour finir&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Je vous propose de considérer que le projet innovant ne doit pas avoir de fin. Il doit être dans une situation de perfectionnement constant. Au même titre que les hommes et femmes qui le bâtisse et se perfectionnent avec lui. &lt;br /&gt;
S’il y a bien un avantage avec les projets web, c’est qu’il est facile de les considérer de cette façon.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;i&gt;« …seuls vivent ceux qui n&amp;#8217;ont point trouvé leur paix dans les provisions qu&amp;#8217;ils avaient faites… &lt;/i&gt;» &amp;#8211; Antoine de Saint Exupéry&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/30/geston-de-projet-innovant.html</link>
			</item>
		
			<item>
				<title>Thème Textmate ParisByNight</title>
				<description>&lt;p&gt;
Juste une petite note pour partager simplement le thème Textmate que j&amp;#8217;ai réalisé
(lorsque je ne me sers pas de Vim ).
&lt;br/&gt;
&lt;a href=&quot;/images/ParisByNight.tmTheme&quot; rel=&quot;nofollow&quot;&gt;Paris By Night&lt;/a&gt;
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/th1.png&quot;/&gt;&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/th2.png&quot;/&gt;&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/21/theme-textmate-parisbynight.html</link>
			</item>
		
			<item>
				<title>Le design pattern Singleton avec Ruby</title>
				<description>&lt;p&gt;
Il y a quelques années lorsque je développais quotidiennement en Java, j&amp;#8217;exploitais beaucoup les Design Pattern:
Facade, Factory, Singleton, &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt;, etc.
Les Design Pattern, quelque soit le langage utilisé, permettent de répondre à des problématiques logiques par des solutions connues de tous.
&lt;/p&gt;
&lt;p&gt;
L&amp;#8217;arrivée des frameworks comme Ruby On Rails a mis en évidence ce genre de pratiques au sein de travaux web.
On utilise régulièrement Model View Controller, &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt;, etc. Je vais donc essayer de faire plusieurs articles sur
l&amp;#8217;utilisation des design pattern en ruby pour la conception web puis d&amp;#8217;expliquer leurs fondements et leur utilité.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/uml.png&quot;/&gt;&lt;/p&gt;
&lt;h2&gt;Singleton en Ruby&lt;/h2&gt;
&lt;p&gt;
L&amp;#8217;objectif de Singleton est d&amp;#8217;instancier une seule fois une classe dans le déroulement du programme.
Lorsque l&amp;#8217;on appel la procédure getInstance (ou instance) on récupère l&amp;#8217;objet unique.
&lt;br/&gt;
En Ruby, l&amp;#8217;utilisation de Singleton est facilité.
Je propose donc un exemple simple pour présenter l&amp;#8217;utilisation du design pattern Singleton en Ruby.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#encoding: utf-8&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;singleton&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyClass&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:data&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Singleton&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MyClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#on instancie pour la première fois, l&amp;#39;objet va donc être créé en mémoire&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MyClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#on récupère l&amp;#39;instance, sans savoir sans avoir besoin de savoir si l&amp;#39;objet a déjà été créé en mémoire&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# b.data possède la même valeur que a.data car c&amp;#39;est la même instance&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Un autre exemple plus pragmatique d&amp;#8217;utilisation de Singleton pour gérer les log d&amp;#8217;un programme.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#Encoding: utf-8&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;singleton&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AppLogger&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Singleton&lt;/span&gt;
  
  &lt;span class=&quot;kp&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:level&lt;/span&gt;
  
  &lt;span class=&quot;no&quot;&gt;ERROR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;WARNING&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;app.log&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;WARNING&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flush&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;WARNING&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flush&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flush&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;AppLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;AppLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INFO&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;la procédure a bien été exécutée&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Plantage...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/20/ruby-design-pattern-singleton.html</link>
			</item>
		
			<item>
				<title>iTerm 2</title>
				<description>&lt;p&gt;
Lorsque l&amp;#8217;on développe sous Mac et plus généralement sous système &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt;, il faut admettre que
le terminal fait parti du quotidien.
Mac OS X Lion a apporté son lot de nouvelles fonctionnalités.
Notamment un gestion approfondie des onglets et d&amp;#8217;autres détails esthétiques comme la transparence et le blur.
&lt;/p&gt;
&lt;p&gt;
Je me serais probablement contenté du terminal par défaut si je n&amp;#8217;utilisais pas les fonctionnalités de split de Vim
très utiles lorsque l&amp;#8217;on code avec Ruby On Rails.
&lt;/p&gt;
&lt;p&gt;
J&amp;#8217;ai découvert il y quelques semaines &lt;a href=&quot;http://www.iterm2.com/&quot;&gt;iTerm2&lt;/a&gt;.
Ce terminal ajoute certaines fonctionnalités dont une très intéressante: le split vertical.
Cette fonctionnalité est extrêmement utile lorsque que l&amp;#8217;on travail avec une connexion &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; pour
une opération de maintenant ou pour afficher les logs d&amp;#8217;un serveur web ruby par exemple.
&lt;/p&gt;
&lt;p&gt;
Toutefois, cette version d&amp;#8217;iTerm2 possède quelques problèmes.
Il est par exemple nécessaire de mapper certaines touches sur les claviers francophones.
Je pense notamment au ALT+Fleches pour déplacer le curseur de mot en mot.&lt;br/&gt;
Pour ce faire, il suffit de suivre les éléments de la capture ci-dessous afin de résoudre ce problème
et mapper le bon raccourcis clavier.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/iterm2.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
&amp;#8220;b&amp;#8221;, pour revenir sur le mot précédent. &amp;#8220;f&amp;#8221;, pour pousser le curseur au mot suivant.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/15/iterm2.html</link>
			</item>
		
			<item>
				<title>Synchroniser ses données avec rsync</title>
				<description>&lt;p&gt;
Les systèmes de cloud ont permis l&amp;#8217;émergence des sauvegardes projetées sur des serveurs distants.
Les particuliers utilisent souvent des systèmes comme Dropbox, Box.net.
&lt;/p&gt;
&lt;p&gt;
Mais lorsque l&amp;#8217;on possède un serveur dédié, comme un Kimsufi, il est plus pertinent de synchroniser ses données sur celui-ci.
&lt;br/&gt;
Cette opération est facilité par l&amp;#8217;utilitaire RSync.
&lt;/p&gt;
&lt;h2&gt;RSync&lt;/h2&gt;
&lt;p&gt;
Au dela de projeter les données sur un serveur distant, RSync a la particularité de
réaliser des sauvegardes incrémentales. C&amp;#8217;est à dire que seules les nouvelles données et les celles modifiées sont envoyées sur le serveur.
&lt;br/&gt;
Ceci a pour intérêt de limiter la consommation de bande passante et surtout le temps de ce type d&amp;#8217;opération.
&lt;br/&gt;
J&amp;#8217;utilise la commande suivante:
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;rsync -auv --del --stats ~/mon_repertoire_a_sauver user@serveur.com:~/backup/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
L&amp;#8217;option a (archiver) permet de conserver les paramètres des fichiers (droits, propriétaire, lien symbolique, etc.).&lt;br/&gt;
v (verbose) affiche les traces.&lt;br/&gt;
u (update) ne copie pas les fichiers qui n&amp;#8217;ont pas changé.&lt;br/&gt;
-del, supprime les fichiers sur le serveur qui ne sont plus présents dans le répertoire d&amp;#8217;origine. Ne pas hésiter à supprimer cette option pour concerver tous les fichiers sur le serveur.&lt;br/&gt;
&amp;#8212;stats, affiche des statistiques en fin d&amp;#8217;opération.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/12/archivage-rsync.html</link>
			</item>
		
			<item>
				<title>Retour aux sources de textmate à VIM</title>
				<description>&lt;h2&gt;De Textmate à &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt;&lt;/h2&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/vim.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
Certains le savent, il y a quelques mois j&amp;#8217;ai
quitté le monde de Textmate pour un retour aux
fondamentaux: le monde de &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt; !
&lt;/p&gt;
&lt;p&gt;
Durant une grande partie de mes études j&amp;#8217;ai passé
mon ordinateur portable sous linux. Sur une promo.
de 300 élèves nous devions être moins de 3
étudiants à utiliser linux au quotidien. C&amp;#8217;était une Fedora 2 ! Depuis, les temps ont changés, je
vois régulièrement des jeunes très à l&amp;#8217;aise sous
linux. Ubuntu doit être pour quelque chose.
&lt;/p&gt;
&lt;p&gt;
Cependant, en 2005, je suis rapidement passé sous
Mac.&lt;br/&gt;
Pas par effet de mode, non, juste par nécessité d&amp;#8217;avoir
Photoshop nativement sous la main. Lorsque l&amp;#8217;on
est concepteur Web, ce petit programme peut aider :)
&lt;/p&gt;
&lt;p&gt;
Sous Mac, j&amp;#8217;ai très rapidement été séduit par Textemate.
D&amp;#8217;abord par sa légèreté, sa sobriété mais
principalement par toutes ses commandes
ésotériques, fermées aux profanes mais tellement
productives.
&lt;/p&gt;
&lt;p&gt;
Depuis quelques mois, pour des raisons professionnelles
j&amp;#8217;exploite un poste sous Linux. L&amp;#8217;environnement de
développement que j&amp;#8217;ai mis en place tourne donc autour de &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt;.
&lt;br/&gt;&lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt; est aussi un de ces outils mystique tellement
productif.
&lt;/p&gt;
&lt;p&gt;
Sous Mac, j&amp;#8217;ai découvert &lt;a href=&quot;http://macvim.org/&quot;&gt;MacVIM&lt;/a&gt; qui permet d&amp;#8217;avoir
l&amp;#8217;intégralité des commandes &lt;span class=&quot;caps&quot;&gt;VIM&lt;/span&gt; compatibles Mac.&lt;br/&gt;Je
vais donc réaliser quelques billets de présentation de cet
utilitaire. En attendant, je vous propose mon .vimrc.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;vim&quot;&gt;&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dark&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;colorscheme&lt;/span&gt; vydark &lt;span class=&quot;c&quot;&gt;&amp;quot;une thème dark&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;guioptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-=&lt;/span&gt;T &lt;span class=&quot;c&quot;&gt;&amp;quot;toggle toolbar for MacVim&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;guioptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-=&lt;/span&gt;L &lt;span class=&quot;c&quot;&gt;&amp;quot;toggle left scroll bar&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;guioptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;quot;toggle right scroll bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;90&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;quot;desfault size for MacVim&lt;/span&gt;

map &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;F2&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; :NERDTreeToggle&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;g&lt;/span&gt;:NERDTreeWinPos &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;right&amp;quot;&lt;/span&gt;

map &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;S&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;Right&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; :&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;160&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;quot;Permet d&amp;#39;agrandir la fenêtre rapidement avec Shift+Fleche droite&lt;/span&gt;
map &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;C&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;S&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;Left&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; :&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;

imap &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;S&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;enter&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Esc&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;$&lt;span class=&quot;k&quot;&gt;a&lt;/span&gt;;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;quot;En faisant un Shift+Enter, le curseur est automatique placé en fin de ligne et un ; est placé. Utile en C, C++, Java...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;showmode&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;quot;affiche le mode I,V, etc.&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;guifont&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;Bitstream\ vera\ sans\ mono:h11

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;utf&lt;span class=&quot;m&quot;&gt;-8&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;wildmenu&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;quot;menu lors de l&amp;#39;utilisation de la touche tab&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;t_Co&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;256&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;on&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;number&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ruler&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tabstop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;softtabstop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;shiftwidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;expandtab&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;smartindent&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ai&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cursorline&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;showmatch&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;incsearch&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nobackup&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nowrap&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;autowrite&lt;/span&gt;       &lt;span class=&quot;c&quot;&gt;&amp;quot; Automatically save before commands like :next and :make&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iskeyword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt;_&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;$&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;@&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;%&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;#&lt;span class=&quot;p&quot;&gt;,-&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;gcr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;a&lt;/span&gt;:blinkon0 &lt;span class=&quot;c&quot;&gt;&amp;quot;retire le clignotement du curseur&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/10/retour-aux-sources-textmate-a-vim.html</link>
			</item>
		
			<item>
				<title>Tweets overload et classification automatique</title>
				<description>&lt;h2&gt;Tweets Overload et application des &lt;span class=&quot;caps&quot;&gt;SVM&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;Sur twitter dès qu&amp;#8217;on follow un nombre important de twittos on fait rapidement face à une sur-information. Il y a plusieurs mois, j&amp;#8217;ai partagé ma petite application: &lt;a href=&quot;http://www.timeline4lazy.com&quot;&gt;Timeline4lazy&lt;/a&gt;. Celle-ci permet à ses utilisateurs d&amp;#8217;avoir une visualisation globale de leur timeline twitter. Timeline4lazy analyse en quasi temps réel, les liens partagés sur sa timeline, les hashtags, les mentions et d&amp;#8217;autres informations plus ou moins pertinentes suivant l&amp;#8217;utilisation que l&amp;#8217;on en fait.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans l&amp;#8217;ensemble, je suis satisfait de cette démarche. Elle reste pertinente. Toutefois, je souhaitais aller plus loin.&lt;br /&gt;
En effet, sur Twitter tous les tweets ne sont pas forcément tous intéressant. Je suis donc parti du principe que je pouvais mettre en place un système en mesure de catégoriser automatiquement les tweets de sa timeline en fonction de ses intérêts.&lt;br /&gt;
D&amp;#8217;où l&amp;#8217;introduction suivante à propos des Machines à Support Vecteur.&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Les Séparateurs à Vaste Marge&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;Je pense que tous les lecteurs de ce blog ne sont pas tous des fans de math. Pour résumer, les Séparateurs à Vaste Marge, aussi appelés Machines à Vecteurs Support (Support Vector Machine) sont des algorithmes supervisées développées par Vladimir Vapnik chez AT&amp;amp;T Bells labs dans les années 90. Ces algorithmes sont principalement utilisées en bio-informatique, en finance, en intelligence artificiel et dans le traitement de l&amp;#8217;information.&lt;br /&gt;
Elles cherchent à produire automatiquement des règles à partir d&amp;#8217;un ensemble de données d&amp;#8217;apprentissage contenant des &amp;#8220;exemples&amp;#8221; de données qualifiées.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Les &lt;span class=&quot;caps&quot;&gt;SVM&lt;/span&gt; sont principalement exploitées pour leur capacité de traitement des données de grandes dimensions. En général, les machines à vastes marge ont des propriétés supérieurs, ou au moins égales, à celle d&amp;#8217;un système d&amp;#8217;apprentissage par réseau de neurones.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Dans le principe les &lt;span class=&quot;caps&quot;&gt;SVM&lt;/span&gt; permettent de résoudre des systèmes discriminant et de régression en prédisant une valeur grâce à une fonction. Par exemple, il est possible de séparer automatiquement deux ensembles de valeurs par l&amp;#8217;intermédiaire d&amp;#8217;un hyperplan. Ceci permet de classifier des données projetées.&lt;/p&gt;
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/graph-svm.jpg&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Comme présenté sur le schéma, les &lt;span class=&quot;caps&quot;&gt;SVM&lt;/span&gt; tentent de diviser les deux ensembles de données avec la plus grande marge sur tous les cotés de l&amp;#8217;hyperplan. Dans cet exemple, on part de l&amp;#8217;hypothèse implicite que la plus grande marge ou la distance entre les ensembles de données et l&amp;#8217;hyperplan la plus élevées est la meilleure. Ce système de classification automatique peut par exemple être utilisé pour le traitement d&amp;#8217;informations nuisibles.&lt;/p&gt;
&lt;/p&gt;
&lt;h2&gt;Application simple des &lt;span class=&quot;caps&quot;&gt;SVM&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;Le contexte étant posé, je vous propose une petite application concrète.&lt;br /&gt;
Dans le cadre qui m&amp;#8217;intéresse, je souhaite classifier les tweets automatiquement. C&amp;#8217;est à dire pourvoir prédire les tweets qui m&amp;#8217;intéresseront et ceux qui m&amp;#8217;intéresseront moins. Pour simplifier, on peut dire que les tweets sont des ensembles de termes séparés par des espaces. On peut donc les assimiler à des vecteurs de n dimension, où n représente le nombre de termes.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Par exemple voici 3 tweets&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;twittos1: j&lt;span class=&quot;s1&quot;&gt;&amp;#39;aime les pommes&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;twittos2: j&amp;#39;&lt;/span&gt;aime le nouvel iphone qui est terrible. Vivement sa sortie &lt;span class=&quot;c&quot;&gt;#iphone #apple&lt;/span&gt;
twittos3: j&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;attends avec impatience le nouvel iphone &lt;span class=&quot;c&quot;&gt;#Apple.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;p&gt;Premièrement, il faut nettoyer les données. Tous les caractères sont transformées en minuscule. Puis, on applique un filtre, généralement appelé &amp;#8220;stoplist&amp;#8221; qui permet de supprimer tous les termes ne possédant pas de sens pour notre application: le, est, la, les, à, etc. On va se retrouver avec des termes suivant dont nous allons indexer: aime &amp;#8594; 1, pomme &amp;#8594; 2, nouvel &amp;#8594; 3, iphone &amp;#8594; 4 , terrible &amp;#8594; 5, vivement &amp;#8594; 6, sortie &amp;#8594; 7, apple &amp;#8594; 8, attends &amp;#8594; 9, impatience &amp;#8594; 10&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;On pourrait aussi passer ces termes à un analyser lexical, souvent appelé processus de lemmatisation afin d&amp;#8217;obtenir le lemme de chaque terme, c&amp;#8217;est à dire la forme canonique. Par exemple pour n&amp;#8217;avoir que les verbes l&amp;#8217;infinitif.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Chaque tweets devient un vecteur sur notre espace à 10 dimensions. Si nous constatons la présence d&amp;#8217;un terme sur le tweet, on met 1, etc.&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Nous avons aussi la matrice de qualification du corpus d&amp;#8217;apprentissage: [0, 1, 1]. Le nombre de colonnes correspond au nombre de documents. Ici, j&amp;#8217;indique que seuls les deux derniers documents me semble intéressant.
&lt;/p&gt;
&lt;h2&gt;Classification des tweets&lt;/h2&gt;
&lt;p&gt;
Plutôt que de vous présenter en détail les calculs, je vous propose une implémentation des &lt;span class=&quot;caps&quot;&gt;SVM&lt;/span&gt; en ruby. J&amp;#8217;ai commencé par mettre toutes les données dans une base sqlite. J&amp;#8217;ai qualifié manuellement mes tweets qui m&amp;#8217;intéressaient au moyen d&amp;#8217;une petite application Ruby On Rails. Il suffisait d&amp;#8217;un tableau présentant la liste des tweets. Sur chaque ligne, j&amp;#8217;ai ajouté une liste déroulante afin de définir à quel corpus d&amp;#8217;apprentissage le tweet correspondait. D&amp;#8217;habitude j&amp;#8217;utilise ActiveRecord pour la connexion avec la base de données. Cette fois, j&amp;#8217;ai utilisé Sequel. Pour de plus gros volumes de données, je recommande de ne pas hésiter à utiliser MySQL ou Postgres.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#encoding: utf-8&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;sequel&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;SVM&amp;#39;&lt;/span&gt;
&lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SVM&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqlite&lt;/span&gt;
  
&lt;span class=&quot;n&quot;&gt;tweets_status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:tweets_status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#table où sont qualifiés les tweets [0, 1, 1, 0, ...]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#liste de l&amp;#39;ensemble des tweets en tableau [&amp;quot;j&amp;#39;aime les pommes&amp;quot;, &amp;quot;j&amp;#39;aime mon iphone&amp;quot;, ...]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train_tweets_status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:train_tweets_status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;#tableaux de qualification des tweets [0, 1, 0] &lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_tweets&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:train_tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#le corpus d&amp;#39;apprentissage&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniq&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#on génère un dictionnaire global regroupant l&amp;#39;ensemble de tout les termes des différents corpus&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;vectors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_vectors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dictionary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Parameter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svm_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NU_SVC&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;degree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coef0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;001&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Problem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tweets_status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each_index&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addExample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vectors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kernels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;LINEAR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;POLY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RBF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SIGMOID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;kernel_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Linear&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Polynomial&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Radial basis function&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Sigmoid&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kernels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each_index&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each_index&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;probs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict_probability&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vectors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#puts &amp;quot;Prediction #{pred}, True label: #{labels[i]}, Kernel: #{kernel_names[j]}&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;kernel &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel_names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; errors on the training data&amp;quot;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;test_labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each_index&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;probs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict_probability&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_vectors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; Prediction: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, True label: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Kernel &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel_names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; errors on the test data &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Prochaines étapes&lt;/h2&gt;
&lt;p&gt;
&lt;p&gt;Avec un plus gros volume de données les calculs risques d&amp;#8217;être plus long. Je présenterai donc dans un prochain article la ré-implémenter de cette partie avec l&amp;#8217;aide de Hadoop et notamment Map/Reduce afin d&amp;#8217;effectuer des calculs parallèles.&lt;br /&gt;
A savoir, on peut aussi effectuer de la classification en utilisant les statistiques bayesiennes. Je vais aussi essayer de faire un article sur ces éléments.&lt;/p&gt;
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/10/01/classification-tweets.html</link>
			</item>
		
			<item>
				<title>Gestion de données massives</title>
				<description>&lt;p&gt;
La Stanford university a publié un ensemble de textes sur la gestion des données massives.
Ce point est de plus en plus problématique pour les entreprises.
Quelque soit le secteur d&amp;#8217;activité, il devient de plus en plus stratégique de donner du sens aux données de l&amp;#8217;entreprise.
Malgré les efforts fait sur les matériels, l&amp;#8217;analyse de celles-ci lorsqu&amp;#8217;elles sont volumineuses, reste complexe et long.
Les algorithmes de traitement, jusqu&amp;#8217;alors utilisées dans les domaines du data-mining et de
la business intelligence, rencontrent leurs limites.
&lt;/p&gt;
&lt;p&gt;
Afin de gérer de grands volumes de données, de plus en plus d&amp;#8217;équipes se tournent vers les pratiques NoSQL &lt;a rel=&quot;nofollow&quot; href=&quot;http://fr.wikipedia.org/wiki/NoSQL&quot;&gt;Not Only &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt;&lt;/a&gt;, parfois pour les mauvaises raisons.
Pour le traitement massif de données, on peut aussi citer &lt;a rel=&quot;nofollow&quot; href=&quot;http://fr.wikipedia.org/wiki/MapReduce&quot;&gt;MapReduce&lt;/a&gt;. MapReduce permet
de répartir et de paralléliser des calculs sur de volumineux corpus de données. Par exemple, pour le calcul de la fréquence
d&amp;#8217;apparition de termes dans des textes ou co-occurence (cas de l&amp;#8217;algorithme TF-&lt;span class=&quot;caps&quot;&gt;IDF&lt;/span&gt;).
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://infolab.stanford.edu/~ullman/mmds.html&quot;&gt;Mining of Massive Datasets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/21/gestion-donnees-massives.html</link>
			</item>
		
			<item>
				<title>De l'utilité des wireframes dans la conception d'applications web</title>
				<description>&lt;p class=&quot;image-container&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.flickr.com/photos/baldiri/5735003580/sizes/m/in/photostream/&quot;&gt;&lt;img src=&quot;/images/wireframes.jpg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
Je viens de feuilleter une keynotes ayant pour objet la conception de wireframes.
Aussi appelé prototypage, maquettage ou encore mockups, cette méthode permet de concevoir &amp;#8220;dans le réel&amp;#8221;
une application web en se projetant directement dans l&amp;#8217;interface web, l&amp;#8217;expérience utilisateur et l&amp;#8217;ergonomie générale.
&lt;br/&gt;Cette méthode permet de garantir la compréhension des besoins fonctionnels mais surtout d&amp;#8217;impliquer les différents acteurs du projet.
L&amp;#8217;importance des maquettes réside dans le fait qu&amp;#8217;elles ne font pas intervenir trop de détails. Lors de cette phase du projet,
il est très important de garder une vision très large et globale. Les maquettes sont généralement sans couleur. Seul compte la position des
éléments.
&lt;/p&gt;
&lt;p&gt;
Dans les phases initiales d&amp;#8217;un projet, beaucoup de clients ne savent pas vraiment ce qu&amp;#8217;ils veulent. Par l&amp;#8217;intermédiaire d&amp;#8217;une maquette,
il est donc plus facile de cadrer les demandes. Les intervenants peuvent exprimer clairement leurs idées. Les discussions sont plus faciles.
Ceci a aussi pour effet d&amp;#8217;impliquer l&amp;#8217;ensemble des collaborateurs.
&lt;/p&gt;
&lt;p&gt;
A mon sens, cette façon de concevoir les applications n&amp;#8217;est pas assez exploitées par les agences.
Pourtant avec l&amp;#8217;arrivée des méthodes agiles ceci facilite les opérations de précision des besoins.
&lt;/p&gt;
&lt;h2&gt;Comment utiliser les maquettes&lt;/h2&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/wireframes6.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
Certains prestataires proposent que le client face lui même directement ses maquettes à partir d&amp;#8217;un logiciel.
Je suis contre cette idée. Mon expérience m&amp;#8217;a généralement montré que le client essai d&amp;#8217;exprimer d&amp;#8217;un seul
coup toutes ses idées. Et malheureusement, elles ne sont pas toutes bonnes à prendre&amp;#8230;
&lt;/p&gt;
&lt;p&gt;
Le but d&amp;#8217;une maquette est véritablement de faire murir le projet en avançant étape par étape.
Le prestataire doit donc jouer un rôle de conseil tant sur le plan technique que fonctionnel. Le client doit être accompagné dans cette démarche.
Je pense que le maquettage doit résulter d&amp;#8217;un travail d&amp;#8217;équipe réalisé lors de petites réunions en comité réduit (4 personnes max.), puis être poursuivi par email.
Les outils de maquettage permettant d&amp;#8217;avance dans ce sens.
&lt;/p&gt;
&lt;p&gt;Dans un prochain article je présenterai les outils que j&amp;#8217;utilise. En attendant je vous propose une keynote suivie de quelques ressources web&lt;/p&gt;
&lt;center&gt;
&lt;div style=&quot;width:400px; text-align:center&quot; id=&quot;__ss_4347737&quot;&gt;
&lt;strong style=&quot;display:block;margin:12px 0 4px&quot;&gt;
&lt;a href=&quot;http://www.slideshare.net/tbisaacs/keynote-kungfu-how-to-wireframe-like-a-ninja&quot; title=&quot;Keynote Kung-Fu: How to wireframe like a ninja&quot; target=&quot;_blank&quot;&gt;
Keynote Kung-Fu: How to wireframe like a ninja
&lt;/a&gt;
&lt;/strong&gt;
&lt;iframe src=&quot;http://www.slideshare.net/slideshow/embed_code/4347737&quot; width=&quot;400&quot; height=&quot;330&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;/center&gt;
&lt;h2&gt;Quelques ressources sur les Wireframes&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://boagworld.com/design/wireframing-rules/&quot;&gt;Five Commandments For Wireframing&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://zerogblog.com/2010/07/sometimes-the-best-wireframing-tool-is-a-pencil/&quot;&gt;Sometimes, the best wireframing tool is a pencil&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://madebymany.com/blog/the-future-of-wireframes&quot;&gt;The futur of wireframe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://konigi.com/notebook/right-way-wireframe&quot;&gt;The Right Way to Wireframe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.wireframeshowcase.com/&quot;&gt;Wireframe Showcase&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://speckyboy.com/2010/07/14/a-collection-of-printable-web-browser-sketching-and-wireframe-templates/&quot;&gt;A Collection of Printable Web Browser Sketching and Wireframe Templates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/20/wireframe-web-design.html</link>
			</item>
		
			<item>
				<title>Principe de sécurité avec un échange Diffie Hellman en Ruby</title>
				<description>&lt;p&gt;
&lt;p&gt;Les années 70 ont été marquées par le développement de la cryptographie. Notamment par l’arrivée des systèmes à base de clés publiques et clés privées.  Par exemple, &lt;span class=&quot;caps&quot;&gt;RSA&lt;/span&gt; a été créé en 1977 par Ronald Rivest, Adi Shamir et Loanard Adleman et breveté par le &lt;span class=&quot;caps&quot;&gt;MIT&lt;/span&gt; en 1983.&lt;br /&gt;
Le concept de clés privées/clés publique est très simple à présenter. Il faut imager que chaque individu souhaitant chiffrer ses correspondances possède une clé publique, connue de tous ainsi qu’une clé privée générée en fonction de la précédente.&lt;br /&gt;
&lt;br/&gt;Il faut bien comprendre que ces clés sont générées mathématiquement l’une en fonction de l’autre mais ne sont pas identiques. On peut dire qu’elles sont sœurs mais pas jumelles. En général, ces clés sont des nombres premiers de grande tailles supérieur à 1024 bits (je détaillerai par la suite).&lt;/p&gt;
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/img33.png&quot;/&gt;&lt;/p&gt;
&lt;h3&gt;Procédure de chiffrement&lt;/h3&gt;
&lt;p&gt;Généralement, le processus fonctionnel de chiffrement est très simple : lorsque Bob souhaite envoyer un message à Alice, celui-ci récupère la clé publique de Alice. Bob chiffre le message qu’il souhaite envoyer grâce à cette clé publique d’Alice. Il peut ainsi diffuser le message chiffré par un canal non sécurisé (en général Internet). Alice n’a plus qu’à déchiffrer le message grâce à sa propre clé privée.&lt;/p&gt;
&lt;p&gt;Si Alice souhaite répondre à Bob. Elle récupère la clé publique de celui-ci, chiffre le message de réponse avec cette clé publique de Bob, l’envoi sur un canal non sécurisé. Bob déchiffre le message grâce à sa propre clé privée.&lt;/p&gt;
&lt;h3&gt;Comment cela est-il possible ?&lt;/h3&gt;
&lt;p&gt;Dans l&amp;#8217;exemple ci-dessus on constate que des données sont privées et d&amp;#8217;autres publiques. Tout ceci permet de chiffrer des données malgré que certaines informations passent en clair sur le réseau.&lt;/p&gt;
&lt;p&gt;Le principe repose généralement sur la notion de groupe mathématique. Dans mon exemple ci-dessous, j’ai utilisé celui des entiers modulo p lorsque p est un nombre premier. Il faut utiliser la propriété (gb)a=(ba)b.&lt;/p&gt;
&lt;p&gt;Ce protocole devient sécurisé lorsque que de grands nombres premiers sont utilisés. En effet, brute forcer le protocole en ne connaissant que les données publiques revient à poser le problème du logarithme discret. Par exemple, pour que Eve trouve gab à partir de ga et gb, l’un ou l’autre de ces éléments doivent être élevés à la puissance b (ou a) respectivement.&lt;/p&gt;
&lt;h3&gt;Principe d&amp;#8217;un échange de clé Diffie-Hellman&lt;/h3&gt;
&lt;p&gt;
Ce principe est différent de la procédure présentée ci-dessus. Mais le but reste le même: permettre
un échange d&amp;#8217;un clé privée par l&amp;#8217;intermédiaire du transfère de données publiques pouvant être interceptées.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/diffie-hellman.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Ceci peut être codé en ruby. Voici le code:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#encoding: utf-8&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#Permet un calcul rapide de: g^a mod p&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mod_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#VALEURS INITIALES&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#g et p sont des nombres connus des agents (Alice, Bob). Ils peuvent être selectionnés arbitraitement par Alice lors de l&amp;#39;initialisation de la communication puis diffusés en clair&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# p doit être un nb premier. Utiliser un nombre &amp;gt; à 1024bits (&amp;gt;309 chiffres)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# nb de base: groupe. Utiliser un nombre aléatoire tel que g &amp;lt; p&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#PRINCIPE:&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Alice et Bob ont en commun un nombre premier p et une base g.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Alice choisit un nombre secret a=6&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Utiliser de préférence un nombre de 100 chiffres mininum.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Elle envoie à Bob la valeur g^a [mod p] = 36 [23] = 16&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#A = g**a % p # A = 3**6 % 23&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Alice envoie à Bob: g=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, p=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, A=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Bob choisit à son tour un nombre secret b=15&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Utiliser de préférence un nombre de 100 chiffres mininum.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Bob envoie à Alice la valeur g^b [mod p] = 315 [23] = 12&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#B = g**b % p # B = 3**15 % 23&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#send(&amp;quot;Alice&amp;quot;,B)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Bob envoie à Alice: B=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Alice peut maintenant calculer la clé secrète commune K =&amp;gt; (g^b [mod p])^a [mod p] = 126 [23] = 9&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#kAlice = B**a % p&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;kAlice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;kAlice = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kAlice&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Bob fait de même et obtient la même clé, K, que Alice : (g^a [mod p])^b [mod p] = 1615 [23] = 9&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#kBob = A**b % p&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;kBob&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;kBob   = &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kBob&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/18/exemple-diffie-hellman.html</link>
			</item>
		
			<item>
				<title>Débuter avec Ruby On Rails</title>
				<description>&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/rails3.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
De plus en plus de développeurs s&amp;#8217;intéressent à Ruby On Rails. C&amp;#8217;est une bonne chose
car ce framework de développement web est vraiment mature. La version 3.1 vient tout
juste de sortir.
&lt;/p&gt;
&lt;p&gt;
Il existe une véritable communauté autour de ce framework. Mais par où commencer ?&lt;br/&gt;
J&amp;#8217;ai essayé de recenser les principaux sites web de référence sur ce sujet.
&lt;/p&gt;
&lt;h3&gt;Sites web sur Ruby On Rails&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
Tout d&amp;#8217;abord, il y a &lt;a rel=&quot;nofollow&quot; href=&quot;http://guides.rubyonrails.org/&quot;&gt;LE Guide&lt;/a&gt;. Il rassemble les principales orientations.
&lt;/li&gt;
&lt;li&gt;
Suivi du tuto: &lt;a rel=&quot;nofollow&quot; href=&quot;http://guides.rubyonrails.org/getting_started.html&quot;&gt;Getting Started with Rails&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
Un guide pas à pas &lt;a rel=&quot;nofollow&quot; href=&quot;http://railsforzombies.org/&quot;&gt;Learning Rails the Zombie Way&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
On retrouve des screencasts. Il y a &lt;a rel=&quot;nofollow&quot; href=&quot;http://rubyonrails.org/screencasts/rails3/&quot;&gt;Rails 3 Screencast Series&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
Sans oublier le fameux &lt;a rel=&quot;nofollow&quot; href=&quot;http://www.railscasts.com/&quot;&gt;Railscasts&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
En screencasts payants, il y a &lt;a rel=&quot;nofollow&quot; href=&quot;http://peepcode.com/pages/rails&quot;&gt;Peepcode&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
Niveau texte on peut retrouver &lt;a rel=&quot;nofollow&quot; href=&quot;http://ruby.railstutorial.org/ruby-on-rails-tutorial-book&quot;&gt;Ruby on Rails Tutorial
- Learn Rails by Example &amp;#8211; de
Michael Hartl&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
L&amp;#8217;API est très riche &lt;a rel=&quot;nofollow&quot; href=&quot;http://api.rubyonrails.org/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; RubyOnRails&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://asciicasts.com/&quot;&gt;ASCIICasts&lt;/a&gt; reprend les videos de Railscasts au format texte..
&lt;/li&gt;
&lt;li&gt;
Plusieurs tutoriels sur &lt;a rel=&quot;nofollow&quot; href=&quot;http://net.tutsplus.com/category/tutorials/ruby/&quot;&gt;Nettuts+&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
Un eBook gratuit sur Ruby: &lt;a rel=&quot;nofollow&quot; href=&quot;http://humblelittlerubybook.com/book/&quot;&gt;Humble Little Ruby Book&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.ruby-doc.org/docs/ProgrammingRuby/&quot;&gt;Programming Ruby&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://pine.fm/LearnToProgram/&quot;&gt;Learn To Program&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.sapphiresteel.com/The-Little-Book-Of-Ruby&quot;&gt;The Litte Book Of Ruby&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://rubylearning.com/&quot;&gt;Ruby Learning&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://ruby.learncodethehardway.org/book/&quot;&gt;Learn Code The Hard Way&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.techotopia.com/index.php/Ruby_Essentials&quot;&gt;Ruby Essentials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Pour finir je vous propose le Cheat Sheet de &lt;a rel=&quot;nofollow&quot; href=&quot;http://blog.envylabs.com/Rails_3_Cheat_Sheets.pdf&quot;&gt;Envylabs&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Je vais aussi essayer de faire rapidement un post sur la blogsphère francophone autour de Rails et Ruby, il y a notamment le
blog de &lt;a href=&quot;http://www.camilleroux.com/&quot;&gt;Camille Roux Ingénieur web Rails à Montpellier&lt;/a&gt;.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/08/debuter-ruby-on-rails.html</link>
			</item>
		
			<item>
				<title>10 effets Instagram sous Photoshop</title>
				<description>&lt;p&gt;
Je pense que vous devez connaitre l&amp;#8217;application Intagram. En gros, c&amp;#8217;est un réseau social
permettant de partager des photos de la vie courante.
La valeur ajoutée de cette application est essentiellement centrée autour des effets que l&amp;#8217;on peut
appliquer à ses photos. On retrouve notamment des effets rétro, vieillissant les clichés à la
façon des vielles pellicules.
&lt;br/&gt;
Le lien ci-dessous est un tutoriel présentant différentes techniques sous photoshop permettant d&amp;#8217;arriver
au même résultat. Je vous laisse le lire :)
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a ref=&quot;nofollow&quot; href=&quot;http://www.blog.spoongraphics.co.uk/articles/10-photoshop-actions-to-create-instagram-style-effects&quot;&gt;10 Photoshop Actions to Create Instagram Style Effects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/07/effets-photoshop-instagram.html</link>
			</item>
		
			<item>
				<title>Chiffrement de données avec un tunnel SSH</title>
				<description>&lt;p&gt;
La notion de chiffrement de flux de données est souvent associée aux &lt;span class=&quot;caps&quot;&gt;VPN&lt;/span&gt; (Virtual Private Network &amp;#8211; Réseau Privé Virtuel).
Or il n&amp;#8217;est pas souvent nécessaire de déployer ce type d&amp;#8217;architecture. &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; peut suffire.
&lt;/p&gt;
&lt;p&gt;
En effet, il est très facile d&amp;#8217;utiliser une connexion &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; vers, par exemple, un serveur dédié.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img alt=&quot;Image Sécurité&quot; src=&quot;/images/secu.png&quot;/&gt;&lt;/p&gt;
&lt;h3&gt;Utilisation&lt;/h3&gt;
&lt;p&gt;Lancer la commande suivante dans un shell. Les paramètres &amp;#8220;user&amp;#8221; et &amp;#8220;server&amp;#8221; sont a adapter à votre configuration.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ssh user@server -C -N -D 8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Dans firefox, vous utilisez le mode &lt;span class=&quot;caps&quot;&gt;SOCK&lt;/span&gt; avec les paramètres suivants&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/tunnel-ssh.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Le tour est joué ! Vous avez maintenant une connexion &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; sécurisée entre votre poste et le serveur.&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/06/tunnel-chiffrement-donnees.html</link>
			</item>
		
			<item>
				<title>Exploiter un seul CPU sous linux</title>
				<description>&lt;p&gt;
Lors de l&amp;#8217;exécution d&amp;#8217;une tache nécessitant des calculs importants sur un serveur,
il peut être intéressant de n&amp;#8217;utiliser qu&amp;#8217;un seul coeur du processeur.&lt;br/&gt;
Pour réaliser ceci, il existe un utilitaire: &lt;b&gt;Taskset&lt;/b&gt;.
&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/cpu.jpg&quot;/&gt;&lt;/p&gt;
&lt;h3&gt;Installation de Taskset&lt;/h3&gt;
&lt;p&gt;Sur sytème Redhat (et fedora, et centos), tasket se trouve dans le paquet util-linux.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# yum install util-linux&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Utilisation&lt;/h3&gt;
&lt;p&gt;Pour utiliser la commande sur le processeur désigné par l&amp;#8217;id 1, vous pouvez utiliser la commande ci-dessous:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;taskset -c 1 mon_script.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Si vous comptez utiliser plusieurs coeurs pour exécuter un programme, il suffi de lancer la commande:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;taskset -c 1,2,3 mon_script.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/05/exploiter-un-seul-cpu-linux.html</link>
			</item>
		
			<item>
				<title>Sortie de Postgresql 9.1</title>
				<description>&lt;p&gt;
  Postgresql Global Development Group vient de nous informer de la sortie de Postgres 9.1.
  Cette nouvelle version comporte différentes évolutions,
  notamment la technique des &quot;K plus proches voisins&quot;, la réplication synchrone afin de
  garantir un système de haute disponibilité dans une grappe de serveurs, des tables non tracées afin
  d'améliorer les performances des données volatiles et d'autres nouveautés que je vous laisserai découvrir.
&lt;/p&gt;
&lt;h3&gt;A propos des K plus proches voisins&lt;/h3&gt;
&lt;p&gt;
  Cette technique est surtout utilisée dans le traitement de documents texte,
  notamment en recherche d'informations ou
  dans le Traitement Automatique du Langage (TAL).
  C'est une méthode non supervisée. En gros, le système apprend automatiquement grâce
  à un corpus de données et non de règles prédéfinies par les développeurs.
  La méthode permet de faire ressortir par rapport à un corpus les échantillons les plus proches
  en fonction du calcul d'une distance.
&lt;/p&gt;
&lt;p&gt;
  Cette méthode est par exemple utilisée dans le traitement des spams.
  Dans ce cadre, on part d'un corpus d'emails. Certains de ces email sont considérés comme étant
  des spams. L'annotation de ce corpus est faite à la main a priori.
  Lorsque l'utilisateur va recevoir un nouvel email, celui-ci va être comparé au corpus grâce
  par exemple au calcul de la fréquence d'apparition de termes. On va alors obtenir le calcul d'une
  distance. En général c'est un chiffre compris entre 0 et 1.
  Si ce chiffre est supérieur à seuil défini alors l'email est considéré comme spam.
&lt;/p&gt;
&lt;p&gt;
  Pour en savoir suivez ce lien:
  &lt;a href=&quot;http://www.postgresql.org/&quot;&gt;http://www.postgresql.org/&lt;/a&gt;.
&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/04/sortie-postgresql-9-1.html</link>
			</item>
		
			<item>
				<title>Partage de liens</title>
				<description>&lt;p&gt;Aujourd'hui je partage avec vous quelques liens qui ont retenu mon attention.&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/design1.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
  Au menu: du web desgin. Le premier concerne 10 techniques et astuces de conception d'interface web.
  Le second lien met en évidence l'importance du texte dans la conception web. Suivi d'autres liens liés à
  l'actualité.
  Et enfin, un guide complet sur le design d'interface web &quot;responsible&quot;. En gros, cela concerne la conception
  d'interface web en prenant en compte différents supports: desktop, tablette, mobile, etc.
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://uxdesign.smashingmagazine.com/2009/01/12/10-useful-web-application-interface-techniques/&quot;&gt;
      10 Useful Web Application Interface Techniques&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://sixrevisions.com/web_design/website-introductory-text-tips-examples/&quot;&gt;
      Designing a Website’s Introductory Text: Tips and Examples&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;http://www.smashingmagazine.com/2011/09/13/freebie-facebook-fan-page-gui-psd/&quot;&gt;Freebie: Facebook Fan Page GUI PSD&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href=&quot;http://www.webdesignshock.com/responsive-web-design/&quot;&gt;Responsive Web Design, most complete guide&lt;/a&gt;
  &lt;/li&gt;

&lt;/ul&gt;

</description>
				<link>http://www.pagedegeek.com/2011/09/03/partage-de-liens-1.html</link>
			</item>
		
			<item>
				<title>Hello World en Ruby</title>
				<description>&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/vim.png&quot;/&gt;&lt;/p&gt;
&lt;p&gt;
Dans un précédent article, j&amp;#8217;ai présenté un bout de cote en C++ très simple. Pour le fun voici la même chose en ruby.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#encoding: utf-8&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MaClasse&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;[+] Constructeur de MaClasse: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; from &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;  
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/02/hello-ruby.html</link>
			</item>
		
			<item>
				<title>Juste du C++</title>
				<description>&lt;p&gt;
On m&amp;#8217;a récemment demandé une initiation au C++. Mais quelque chose de très light. Il n&amp;#8217;était pas question d&amp;#8217;aborder les pointeurs. Mon idée était de montrer uniquement l&amp;#8217;aspect objet de C++.
Voici donc un bout de code très simple.
&lt;br/&gt;Il se compose:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;du programme principal: hello.cpp.&lt;/li&gt;
  &lt;li&gt;d&amp;#8217;un fichier entête d&amp;#8217;une classe: ma_classe_.h&lt;/li&gt;
  &lt;li&gt;du code d&amp;#8217;une classe: ma_classe.cpp&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Le fichier hello.cpp est la partie principale du programme. C&amp;#8217;est ici que les classes vont être &lt;a href=&quot;http://fr.wiktionary.org/wiki/instancier&quot;&gt;instanciées&lt;/a&gt; en objet.
&lt;/p&gt;
&lt;p&gt;
On retrouve aussi l&amp;#8217;entête (ma_classe.h) et le code (ma_classe.cpp). Dans le premier fichier on déclare les fonctions essentielles de la classe. Dans l&amp;#8217;autre fichier, il y a la logique applicative.
&lt;/p&gt;
&lt;p&gt;# ma_classe.h&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;string&amp;gt;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Ne pas oublier ce point virgule !!!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Dans ma_classe.h, on trouve la déclaration de la classe: &amp;#8220;class MaClasse{}&amp;#8221;. La déclaration d&amp;#8217;une variable de type entier: &amp;#8220;int id&amp;#8221;.
On trouve aussi deux constructeurs. L&amp;#8217;un sans argument l&amp;#8217;autre avec: &amp;#8220;MaClasse()&amp;#8221; et &amp;#8220;MaClasse(int id)&amp;#8221;.
Suivi du destructeur: &amp;#8220;~MaClasse()&amp;#8221;.
&lt;br/&gt;
Et enfin, les fonctions accessibles par un objet.
&lt;/p&gt;
&lt;p&gt;# ma_classe.cpp&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;string&amp;gt;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include &amp;quot;ma_classe.h&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;[+] Constructeur de MaClasse: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;[+] Constructeur de MaClasse: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;[-] Destructeur de MaClasse: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Hello from MaClasse: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; !&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Hello &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; from MaClasse: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; !&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;# hello.cpp&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;string&amp;gt;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include &amp;quot;ma_classe.h&amp;quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;//Exemple instanciation statique&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mc1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mc1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;//Exemple instanciation dynamique&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mc2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MaClasse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mc2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mc2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Pour compiler ce petit programme&lt;/h3&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;repertoire&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;g++ hello.cpp ma_classe.cpp -o hello
repertoire&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./hello 
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Constructeur de MaClasse: 1
Hello World from MaClasse: 1 !
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Constructeur de MaClasse: 2
Hello World from MaClasse: 2 !
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Destructeur de MaClasse: 2
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Destructeur de MaClasse: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/img31.png&quot;/&gt;&lt;/p&gt;</description>
				<link>http://www.pagedegeek.com/2011/09/01/juste-du-cpp.html</link>
			</item>
		
			<item>
				<title>A propos</title>
				<description>&lt;p&gt;
&lt;!-- &lt;span style=&quot;float: right; margin-left: 35px;&quot;&gt;&lt;img style=&quot;border: 1px solid #999; padding: 3px&quot; src=&quot;http://www.gravatar.com/avatar/dc3b35f74d7e1da0d1f0a831605319e3?s=160&quot;/&gt;&lt;/span&gt; --&gt;
Sur &lt;a href=&quot;http://www.pagedegeek.com&quot;&gt;Page de Geek&lt;/a&gt;,
je publie des notes tournant autour du web et principalement
de ses technologies. Plusieurs thématiques sont abordées:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;L&amp;#8217;architecture des technologies web&lt;/li&gt;
	&lt;li&gt;Ruby On Rails&lt;/li&gt;
	&lt;li&gt;Mysql, Postgresql et &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt;&lt;/li&gt;
  &lt;li&gt;Les base de données NoSQL (MongoDB, Redis, Hadoop, etc.)&lt;/li&gt;
  &lt;li&gt;Le traitement de données (Map/Reduce, Data Mining, etc.)&lt;/li&gt;
	&lt;li&gt;La sécurité de l&amp;#8217;information&lt;/li&gt;
	&lt;li&gt;Le référencement, &lt;span class=&quot;caps&quot;&gt;SEO&lt;/span&gt;&lt;/li&gt;
  &lt;li&gt;Le Web Analytics&lt;/li&gt;
	&lt;li&gt;Html et &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;Les univers Linux et Mac&lt;/li&gt;
	&lt;li&gt;Le web en général&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;A propos de moi ?&lt;/h3&gt;
&lt;p&gt;Très tôt, avant les années 2000, je suis tombé dans le chaudron d&amp;#8217;internet. C&amp;#8217;était l&amp;#8217;époque des modems &lt;span class=&quot;caps&quot;&gt;RTC&lt;/span&gt;, des disquettes, de Altavista, du langage Pascal, de SoftIce et d&amp;#8217;autres geekeries. Je devais tout juste avoir 12 ou 13 ans. Depuis, je n&amp;#8217;ai jamais vraiment quitté l&amp;#8217;univers du web.&lt;/p&gt;
&lt;p&gt;J&amp;#8217;ai effectué un parcours universitaire atypique et pluridisciplinaire dans lequel j&amp;#8217;ai évolué entre les technologies web, la communication, le design, le management de projet et la sécurité. J&amp;#8217;ai eu plusieurs expériences professionnelles enrichissantes. Comme développeur web, développeur Java, architecte SI, directeur de projet. A ce jour, je travaille comme directeur technique au sein d&amp;#8217;une société de communication.&lt;/p&gt;
&lt;p class=&quot;image-container&quot;&gt;&lt;img src=&quot;/images/img23.png&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Retrouvez-moi sur d&amp;#8217;autres espaces web&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.twitter.com/pagedegeek&quot;&gt;Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/PagedeGeek&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.flickr.com/photos/samditbien&quot;&gt;Flickr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
				<link>http://www.pagedegeek.com/2011/08/30/a-propos-page-de-geek.html</link>
			</item>
		
	</channel>
</rss>