<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Jérémy Lecour</title>
	<atom:link href="http://jeremy.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeremy.wordpress.com</link>
	<description>Concepteur et développeur d'applications web</description>
	<lastBuildDate>Tue, 17 Jan 2012 14:07:55 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='jeremy.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Jérémy Lecour</title>
		<link>http://jeremy.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://jeremy.wordpress.com/osd.xml" title="Jérémy Lecour" />
	<atom:link rel='hub' href='http://jeremy.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Sauvegarder une branche git, sans empêcher les rebase</title>
		<link>http://jeremy.wordpress.com/2012/01/17/sauvegarder-une-branche-git-sans-empecher-les-rebase/</link>
		<comments>http://jeremy.wordpress.com/2012/01/17/sauvegarder-une-branche-git-sans-empecher-les-rebase/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 11:00:00 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[verisoning]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=378</guid>
		<description><![CDATA[Je suis assez régulièrement dans une situation où je travaille sur une branche de longue durée (plus de quelques jours), appelons la big_feature. Pour maintenir cette branche à jour par rapport à master, j’utilise de préférence git rebase (par rapport à git merge). Ça donne par exemple : $ git checkout big_change $ git rebase [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=378&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Je suis assez régulièrement dans une situation où je travaille sur une branche de longue durée (plus de quelques jours), appelons la <code>big_feature</code>.</p>
<p>Pour maintenir cette branche à jour par rapport à <code>master</code>, j’utilise de préférence <code>git rebase</code> (par rapport à <code>git merge</code>).</p>
<p>Ça donne par exemple :</p>
<pre><code>$ git checkout big_change</code>
<code>$ git rebase master</code></pre>
<p>Le problème est que si je pousse ma branche <code>big_change</code> sur un dépôt distant, les “rebase” deviennent dangereux. Mais si je ne pousse jamais cette branche, et que je perds le contenu de mon dépôt local, alors je perds tout mon travail sur cette branche.</p>
<p>Évidemment, tout développeur sérieux dispose de sauvegardes de son poste de travail, mais selon les outils il peut être fastidieux d’y accéder juste pour quelques fichiers. Et puis il y a ceux qui n’ont aucune sauvegarde (les fous !). Pourquoi ne pas utiliser Git pour ça ?</p>
<p>Je me suis donc créé un petit script (accessible depuis mes dépôts) qui me permet de pousser ma branche courante sur un dépôt distant (<code>origin</code> par convention, modifiable en ajoutant un paramètre à l&#8217;appel du script), mais de manière à identifier qu’elle n’est qu’à des fins de sauvegarde.</p>
<pre><code>#!/bin/sh</code>
<code>set -e</code>
<code>CUR=`git branch | grep '\*' | awk '{print $2}'`</code>
<code>REM=${1:-'origin'}</code>
<code>git push --force ${REM} ${CUR}:backup/${USER}/${CUR}</code></pre>
<p>On trouvera donc sur le dépôt distant, un groupe de branches appelées “backup”, puis un sous-groupe pour chaque développeur, dans lequel il y trouvera ses branches de sauvegardes, nommées comme ses branches locales.</p>
<p>Ça crée donc une convention, facile à comprendre.</p>
<p>Plus généralement, si il y a un ou plusieurs “/” dans le nom d’une branche, Git va traiter ça comme des portions d’arborescence de système de fichier et grouppera donc toutes les branches dans les mêmes dossiers et éventuellement sous-dossiers.</p>
<p>J’utilise ce système pour toutes les branches qui correspondent à des fonctionnalités, par exemple :</p>
<ul>
<li>features/new_login</li>
<li>features/alternate_footer</li>
<li>…</li>
</ul>
<p>Ainsi dans les outils (graphiques ou en mode texte), je vois ces branches groupées, voire même de manière arborescente. Si vous ouvrez le dossier “.git” de votre dépôt, vous verrez que Git crée réellement des dossiers et sous-dossiers dans “.git/refs/heads” et “.git/refs/remotes/xyz/” et les branches y sint de vrais fichiers appelés comme la dernière partie du nom donné à la branche.</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/git/'>git</a>, <a href='http://jeremy.wordpress.com/tag/verisoning/'>verisoning</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/378/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=378&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2012/01/17/sauvegarder-une-branche-git-sans-empecher-les-rebase/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>Répondre à une offre d&#8217;emploi ou de stage : les bonnes et mauvaises pratiques</title>
		<link>http://jeremy.wordpress.com/2011/10/28/candidature-emploi-stage-bonnes-mauvaises-pratiques/</link>
		<comments>http://jeremy.wordpress.com/2011/10/28/candidature-emploi-stage-bonnes-mauvaises-pratiques/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 13:26:02 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[conseils]]></category>
		<category><![CDATA[recrutement]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=370</guid>
		<description><![CDATA[En ce moment, je suis en situation de recrutement de stagiaires, et je l&#8217;ai été plusieurs fois ces dernières années. Je reçois et traite de nombreuses candidatures. Ça m’a permis de compiler cette série de bonnes et mauvaises pratiques que je retranscrit ici sous forme de conseils bienveillants. Imaginons que vous êtes candidat, que ma société s’appelle BigCorp et [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=370&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>En ce moment, je suis en situation de <a href="https://gist.github.com/606338">recrutement de stagiaires</a>, et je l&#8217;ai été plusieurs fois ces dernières années. Je reçois et traite de nombreuses candidatures. Ça m’a permis de compiler cette série de bonnes et mauvaises pratiques que je retranscrit ici sous forme de conseils bienveillants.</p>
<p>Imaginons que <strong>vous êtes candidat</strong>, que <strong>ma société s’appelle BigCorp</strong> et que je m’adresse à vous.</p>
<h2>Postuler ou pas ?</h2>
<p>Arroser la planète entière avec votre CV n’a que peu de chances de vous trouver un travail.</p>
<p>Cherchez bien à <strong>identifier le profil</strong> recherché et voir si vous pensez correspondre.</p>
<p>Si le profil recherché est expérimenté dans la construction de sites web de e-commerce et que vous êtes en première année d’IUT informatique de gestion, sans réelle expérience personnelle, ou bien si c’est un administrateur système qui est recherché alors que vous avez juste un peu bidouillé votre PC à la maison, <strong>ne répondez pas</strong>. Vous gagnerez du temps et surtout vous en économiserez au recruteur. Imaginez que vous soyez pris sur un malentendu ; c’est perdant-perdant.</p>
<h2>Le mail de réponse</h2>
<p>Si vous connaissez l’identité du destinataire, indiquez la en début de message lorsque vous vous adressez à lui/elle. Pas de “<strong>Madame, Monsieur, Mademoiselle</strong>” si vous savez que c’est <strong>Martine Durand</strong> qui est responsable de recrutement.</p>
<p>Indiquez à quelle offre vous répondez (et si possible comment vous l’avez trouvée), car il peut y avoir plusieurs recrutements en même temps dans l’entreprise.</p>
<p>Soyez attentif à la forme de votre message : politesse, orthographe, phrases courtes et bien construites, … Vous perdez de sérieux points lorsque vous laissez traîner plus d’une ou deux fautes d’orthographe dans votre message, lorsque la ponctuation est très mal (ou pas) utilisée, …</p>
<p>L’idéal est de coller au style de l’annonce sur le niveau de langage, le style de phrases, … Ça n’est pas simple, mais vous marquerez des points si c’est remarqué.</p>
<p>J’ai tendance à préférer l’expression de la motivation d’un candidat dans ce mail de réponse plutôt qu’un message presque vide et une pièce jointe “Lettre de motivation”.</p>
<p>Soyez original(e) si vous pensez que ça peut s’y prêter. Il n’est pas interdit de sortir du cadre des conventions classiques. Les meilleurs recrutements que j’ai fait sont souvent des personnes qui ont sur se différencier par le fond et la forme. Par contre c’est un exercice difficile car on peut aussi totalement tomber à côté de la plaque.</p>
<h2>La “lettre de motivation”</h2>
<p>Son but est de montrer que vous avez envie d’intégrer l’entreprise qui recrute et que vous lui apporterez ce qu’elle attend.</p>
<p>Ne sortez pas les phrases toutes faites, apprises à l’école. N’expliquez pas au recruteur ce qu’il sait déjà de son entreprise, surtout si c’est pour dire n’importe quoi (“Votre entreprise, leader sur son marché et son territoire” lorsque c’est une PME de 3 salariés). Trouvez d’autres moyens pour montrez que vous avez fait des recherches sur l’entreprise. Si elle dispose d’un blog, vous y trouverez des infos pertinentes pour comprendre la culture de l’entreprise, qui y travaille, …</p>
<p>Énumérer vos qualités risque de rapidement tomber dans les “sens des responsabilité”, “qualité relationnelle”, … qu’on attend presque toujours chez tout candidat. Indiquez plutôt ce qui peut vous démarquer au niveau de vos expériences, de votre parcours, … et qui est particulièrement adapté à l’entreprise.</p>
<p>Si vous y croyez, expliquez pourquoi vous pensez que n’êtes pas simplement “bon pour le poste”, mais le/la meilleur. Si vos arguments sont bons, ça ne passera pas pour de l’égocentrisme et de la vanité.</p>
<h2>Le CV</h2>
<p>Le CV est un piège dans lequel il est facile de tomber car les écoles nous apprennent souvent à faire des mauvais CV.</p>
<p>Soyez succinct ; le plus souvent 1 seule page suffit et pour ça il convient de bien choisir ce qu’on met en avant.</p>
<p>Tous les logiciels que vous avez utilisé, tous les micro-stages dans des entreprises qui n’ont rien à voir avec l’offre, le baby-sitting, … n’ont pas besoin de se trouver sur votre CV. Idem pour les hobbies personnels, mentionnez les s’il vous reste de la place.</p>
<p>Choisissez ce qui correspond particulièrement au profil du poste, quitte à mentionner que ça n’est pas tout et que seriez ravi de discuter de vos diverses expériences en annexes.</p>
<p>Si votre profil vous permet de postuler plusieurs offres, personnalisez un CV par poste, pour être bien ciblé.</p>
<p>Dans sa forme, un CV doit être sobre et très lisible. Si vous mettez une couleur ou un motif de fond, 3 polices de caractères différentes, des encadrés autour de chaque paragraphe, … vous vous y prenez mal.</p>
<p>Il conseillé d’annexer (directement ou avec un lien) un échantillon de vos précédentes réalisations, pourvu que ça soit adapté au poste pour lequel vous postulez. Si vous êtes développeur, indiquez ce qui est consultable en ligne (compte GitHub ou autre), un portfolio si vous êtes graphiste, …</p>
<h2>Les pièces jointes</h2>
<h3>Format des fichiers</h3>
<p>Il est indéniable que <strong>Microsoft Word</strong> est très répandu (bien que je doute que la plupart étudiants ait une licence valide), mais ça n’est pas non plus le standard.</p>
<p>J’ai le droit de ne pas vouloir payer plusieurs centaines d’Euros pour une licence entreprise de ce produit, ou bien d’utiliser un système sur lequel il n’est pas disponible. En m’imposant ce format propriétaire, vous réduisez les chances que je puisse consulter votre candidature.</p>
<p>Il existe cependant des formats libres, plus ouverts, et encore plus répandus.</p>
<ul>
<li>le <strong>texte brut</strong> : c’est assez rustique, mais la solution ultime en terme d’accessibilité. Le plus souvent, un CV n’a pas besoin de faire preuve d’une grande créativité en terme de mise en forme. Si vous êtes dans des métiers de l’image, créez des documents adaptés : animés ou statiques selon, mais qui correspondent au destinataire.</li>
<li id="scroll_to_here">le <strong>RTF</strong> : il permet une mise en forme plus riche, il est tout à fait standard et tous les logiciels de traitement de texte savent lire et exporter ce type de document.</li>
<li>le <strong>PDF</strong> : bien que format pas totalement libre, il existe des “lecteurs de PDF” pour quasiment tous les systèmes. Il a l’avantage de permettre une mise ne forme très poussée, une bonne accessibilité s’il est bien construit, peut être imprimé sans dégradation de format, …</li>
</ul>
<h3>Nom de chaque document</h3>
<p>Le plus souvent, lorsqu’une entreprise publie une offre, elle ne reçoit pas seulement votre candidature.</p>
<p>Des documents qui s’appellent “<em>CV.doc</em>”, “<em>LM.doc</em>”, “<em>profil.doc</em>” ou encore “<em>modèle.doc</em>” deviennent totalement anonymes lorsqu’ils sont sortis du contexte du mail auquel ils étaient joints. Je classe tous ces documents dans un dossier correspondant au recrutement en cours. Il m’est donc beaucoup plus utile d’avoir des fichiers du genre “<em>John Doe &#8211; CV.pdf</em>”, “<em>John Doe &#8211; LM BigCorp.pdf</em>”.</p>
<ul>
<li><strong>votre nom</strong> en début permet de grouper plusieurs documents vous concernant lors d’un tri alphabétique.</li>
<li>indiquez ensuite le <strong>type de document</strong> s’il y en a plusieurs.</li>
<li>si votre lettre de motivation est personnalisée (fortement conseillé), indiquez le nom de l’entreprise destinataire, ça montre un effort d’adaptation.</li>
</ul>
<h2>Conclusion</h2>
<p>Avec un minimum d&#8217;effort, c&#8217;est finalement assez facile de ne pas faire mauvaise impression lorsqu&#8217;on postule à une offre d&#8217;emploi ou de stage. Et si vous faîtes cet effort, vous serez probablement remarqué(e) et vous marquerez de précieux points lorsqu&#8217;il faudra décider de ne pas faire passer votre candidature dans la corbeille, mais à l&#8217;étape suivante de la sélection.</p>
<p><em><strong>Mise à jour (31/11/2011)</strong></em> : Sur <a href="http://j-mad.com/blog/2011/10/31/repondre-a-une-offre-de-stage-mon-avis/">son blog</a>, J-Mad complète judicieusement mes conseils.</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/conseils/'>conseils</a>, <a href='http://jeremy.wordpress.com/tag/recrutement/'>recrutement</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/370/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=370&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2011/10/28/candidature-emploi-stage-bonnes-mauvaises-pratiques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>Tutorat technique : tiens, c&#8217;est cadeau !</title>
		<link>http://jeremy.wordpress.com/2011/10/28/tutorat-technique-tiens-c-est-cadeau/</link>
		<comments>http://jeremy.wordpress.com/2011/10/28/tutorat-technique-tiens-c-est-cadeau/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 08:57:15 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[laboate]]></category>
		<category><![CDATA[Personnel]]></category>
		<category><![CDATA[PLUG]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=362</guid>
		<description><![CDATA[Je fais partie de ceux qui croient que lorsqu&#8217;on débute ou qu&#8217;on cherche à se perfectionner dans une pratique, être accompagné d&#8217;un &#8220;mentor&#8221; (ou tuteur, si vous préférez) est une grande aide. J&#8217;ai pu en bénéficier quelques fois à mes débuts (trop peu à mon goût, d&#8217;ailleurs) et ça m&#8217;a beaucoup servi. C&#8217;est pourquoi je [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=362&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Je fais partie de ceux qui croient que lorsqu&#8217;on débute ou qu&#8217;on cherche à se perfectionner dans une pratique, être accompagné d&#8217;un &#8220;mentor&#8221; (ou tuteur, si vous préférez) est une grande aide.</p>
<p>J&#8217;ai pu en bénéficier quelques fois à mes débuts (trop peu à mon goût, d&#8217;ailleurs) et ça m&#8217;a beaucoup servi.</p>
<p>C&#8217;est pourquoi je voudrais consacrer un peu de mon temps, régulièrement (et gratuitement), pour accompagner des personnes qui souhaiterais avoir un œil extérieur sur leur code, leurs pratiques, leurs méthodes, leurs outils, …</p>
<p>Il ne s&#8217;agit pas de formation au sens institutionnel du terme, mais plutôt d&#8217;observation, de critique et de conseil, dégagé de tout troll (dans la mesure du plus possible).</p>
<p>Je propose donc de passer 30 minutes à 1h en tête-à-tête, lors de chaque réunion du PLUG, avec une personne pour une séance de pair-programming, ou de discussion technique sur un sujet, … Ça peut être sur mes technos de prédilection, mais aussi sur n&#8217;importe quel langage, framework, … ou sur des méthodes de travail car il ne s&#8217;agit pas forcément de décortiquer le détail de chaque ligne, mais pourquoi pas d&#8217;avoir un regard critique d&#8217;ensemble, …</p>
<p>Faites moi signe (en commentaire, par e-mail, via <a title="jlecour : Jérémy Lecour sur Twitter" href="http://twitter.com/jlecour">Twitter</a>, …) si vous êtes intéressé. On peut faire une tentative dès la prochaine <a href="http://plugfr.org/r/188/">réunion du PLUG, le 4 novembre</a>. En cas de demandes multiples, je me réserve la liberté de choisir le sujet avec lequel je me sentirai le plus à l&#8217;aise ou le plus intéressé.</p>
<p><strong>Mise à jour (21/11/2011)</strong> : La première tentative est concluante (pour moi au moins), donc je propose de recommencer dès la <a href="http://plugfr.org/r/189">réunion du PLUG le 2 décembre</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/362/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=362&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2011/10/28/tutorat-technique-tiens-c-est-cadeau/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>API Versioning in Rails with Accept HTTP headers</title>
		<link>http://jeremy.wordpress.com/2011/10/07/api-versioning-in-rails-with-accept-http-headers/</link>
		<comments>http://jeremy.wordpress.com/2011/10/07/api-versioning-in-rails-with-accept-http-headers/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 06:38:24 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[versioning]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=351</guid>
		<description><![CDATA[To implement API versioning in Rails, not using URL namespaces but custom MIME types, there are a few different approches. The Tribesports way Recently, I&#8217;ve seen a blog post about the Tribesports API. They chose to add a new MIME type to the application and use the rendering features of Rails. Maybe I&#8217;ve not seen [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=351&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>To implement API versioning in Rails, not using URL namespaces but custom MIME types, there are a few different approches.</p>
<h2>The Tribesports way</h2>
<p>Recently, I&#8217;ve seen a blog post about the <a href="http://techblog.tribesports.com/blog/2011/09/24/versioning-the-tribesports-api/">Tribesports API</a>. They chose to add a new MIME type to the application and use the rendering features of Rails.</p>
<p>Maybe I&#8217;ve not seen all the constraints they might have, and that lead to this choice, but from my point of view, 2 things are bothering me :</p>
<ol>
<li>they had to change too much things in the rendering process</li>
<li>they created the <code>api_v1</code> content type but in fact it&#8217;s plain JSON</li>
</ol>
<p>What if they wanted to render JSON or XML but for the version 1 of their API ?</p>
<h2>Another way</h2>
<p>With a simple protected method in the ApplicationController, it&#8217;s possible to inspect the <code>Accept</code> HTTP header, and extract an API version number, while letting Rails decide what is the real content type to use.</p>
<p><pre class="brush: ruby;">
class ApplicationController &lt; ActionController::Base

  respond_to :html, :xml, :json

  protected

  def api_version
    default_version = '1'
    pattern = /application\/vnd\.com\.example\.api\.v([\d\.]+)\+.*/
    request.env['HTTP_ACCEPT'][pattern, 1] || default_version
  end
end
</pre></p>
<p>In this example, by default all the action method of all controllers will respond to HTML, XML and JSON, and Rails is probably using the default HTML if nothing is specified. I can even implement a rendering for another format in the respond_to block of a action method, like format.js for Ajax requests, …</p>
<p>We now have a method, accessible from all controller methods (including actions) to get the desired API version nummber. If an &#8220;application/vnd&#8221;-style <code>Accept</code> header is found and if a version number can be extracted, then it is used. There is a fallback to the default version.</p>
<p>With this, you can have any test you want at the controller level on the API version, without messing with the content type.</p>
<p>About the default version number, some prefer the lastest (and allow clients to set a specific version), and some prefer the first version. I prefer the &#8220;latest by default&#8221; way.</p>
<p>NB : I&#8217;m quite sure I&#8217;ve not made this one up, but I honestly can&#8217;t remember where I&#8217;ve read this from.</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/api/'>api</a>, <a href='http://jeremy.wordpress.com/tag/http/'>http</a>, <a href='http://jeremy.wordpress.com/tag/rails/'>rails</a>, <a href='http://jeremy.wordpress.com/tag/ruby/'>ruby</a>, <a href='http://jeremy.wordpress.com/tag/versioning/'>versioning</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/351/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=351&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2011/10/07/api-versioning-in-rails-with-accept-http-headers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>You have modified your Gemfile in development</title>
		<link>http://jeremy.wordpress.com/2011/03/18/you-have-modified-your-gemfile-in-development/</link>
		<comments>http://jeremy.wordpress.com/2011/03/18/you-have-modified-your-gemfile-in-development/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 18:21:37 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[bundler]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=339</guid>
		<description><![CDATA[Twice this week I&#8217;ve had a problem with Bundler (1.0.10). During a deploy with Capistrano, I had some errors like this : I&#8217;ve searched in Google for this kind of errors, and everything I&#8217;ve found was dealing with .bundle directories, ignoring and tracking again the Gemfil.lock, … but nothing worked for me. It was stupid [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=339&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Twice this week I&#8217;ve had a problem with Bundler (1.0.10).</p>
<p>During a deploy with Capistrano, I had some errors like this :</p>
<p><pre class="brush: plain;">
You have modified your Gemfile in development but did not check
the resulting snapshot (Gemfile.lock) into version control

You have added to the Gemfile:
* roxml (~&gt; 3.1, &lt; 3.1.6)

You have deleted from the Gemfile:
* roxml (&lt; 3.1.6, ~&gt; 3.1)
</pre></p>
<p>I&#8217;ve searched in Google for this kind of errors, and everything I&#8217;ve found was dealing with .bundle directories, ignoring and tracking again the Gemfil.lock, … but nothing worked for me.</p>
<p>It was stupid of me not to follow some basic rules : what does the message tell? It&#8217;s telling that there is a difference between 2 versions. OK, but then there are the differences. It seems to be a matter of order in the version parameters.</p>
<p>All the gems in the Gemfile with none or only one version constraint were OK, and every one with two or more were listed in this error message.</p>
<p>The answer is really straightforward : let&#8217;s inverse the constraints, the &#8216;&lt;&#8217; before the &#8216;~&gt;&#8217;. And it works!</p>
<p>Now I have the solution but not the explanation. I don&#8217;t have any idea why suddenly Bundler was picky like this. I didn&#8217;t even update it.</p>
<p><strong>Update</strong> (<a href="https://github.com/carlhuda/bundler/issues/1080/#issue/1080/comment/890410">quoting Andre Arko</a>, maintainer of Bundler) :</p>
<blockquote><p>This is an issue with Rubygems, which started calling <code>.sort</code> on the requirements list as of Rubygems 1.6 and higher. I&#8217;ve worked around it (just yesterday), and the fix will be in the next release of Bundler 1.0.x.</p></blockquote>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/bundler/'>bundler</a>, <a href='http://jeremy.wordpress.com/tag/rails/'>rails</a>, <a href='http://jeremy.wordpress.com/tag/ruby/'>ruby</a>, <a href='http://jeremy.wordpress.com/tag/rubygems/'>rubygems</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/339/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=339&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2011/03/18/you-have-modified-your-gemfile-in-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>Un proxy qui annule l&#8217;authentification, pourquoi pas ?</title>
		<link>http://jeremy.wordpress.com/2011/01/21/un-proxy-qui-annule-authentification-pourquoi-pas/</link>
		<comments>http://jeremy.wordpress.com/2011/01/21/un-proxy-qui-annule-authentification-pourquoi-pas/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 08:09:51 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Autrement]]></category>
		<category><![CDATA[Informatique]]></category>
		<category><![CDATA[PLUG]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[hotelhotel]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=327</guid>
		<description><![CDATA[Le contexte Voilà une idée bien saugrenue, je vous l&#8217;accorde. Pour comprendre, voyons un peu le contexte. Nous avons développé une application iPhone pour HotelHotel (le site sur lequel je travaille). Elle fonctionne en interrogeant notre API interne pour effectuer des recherches d&#8217;hôtels. L&#8217;API interroge nos partenaires compare les prix et compose une liste de [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=327&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Le contexte</h3>
<p>Voilà une idée bien saugrenue, je vous l&#8217;accorde. Pour comprendre, voyons un peu le contexte.</p>
<p>Nous avons développé une application iPhone pour <a href="http://www.hotelhotel.com/">HotelHotel</a> (le site sur lequel je travaille). Elle fonctionne en interrogeant notre API interne pour effectuer des recherches d&#8217;hôtels. L&#8217;API interroge nos partenaires compare les prix et compose une liste de résultats renvoyée à l&#8217;application iPhone.</p>
<p>Pour les hôtels, nous disposons de plusieurs photos, qui aident à se faire un avis sur les hôtels proposés. Ces photos sont gérées par nous mêmes, nous indiquons juste leur URL à l&#8217;application distante.</p>
<p>Jusqu&#8217;à ces derniers jours, nous stockions ces photos sur notre propre serveur, mais pour différentes raisons, nous les avons déportées vers le service <a href="http://aws.amazon.com/fr/s3/">Amazon S3</a>. Il y a plein d&#8217;avantages à utiliser ce service : haute disponibilité des contenus, bande passante très importante, pas de soucis de croissance de l&#8217;espace utilisé, … pour un coût très raisonnable.</p>
<p>Nous avons donc modifié les différentes parties de notre système pour que les fichiers soient placés sur Amazon S3 et les URL renvoyées aux navigateurs, application iPhone, … soient celle sur Amazon S3 et plus sur notre serveur.</p>
<h3>Le problème</h3>
<p>Jusqu&#8217;ici tout va bien, ou presque. Nos différents sites web (public, admin, …) fonctionnent bien, en lecture comme en écriture. Pa contre, l&#8217;<strong>appli iPhone plante</strong> et quitte dès qu&#8217;on veux <strong>charger une photo</strong>.</p>
<p>Après une séance de debuggage un peu déconcertante, on fini par trouver la source du problème. Pour bien comprendre, je rembobine un peu.</p>
<p>Pendant la phase de développement de l&#8217;appli iPhone, nous utilisions une version privée de l&#8217;API, sur un sous-domaine spécial, protégé par une <a href="http://fr.wikipedia.org/wiki/HTTP_Authentification">authentification HTTP Basic</a>. Juste avant la publication sur l&#8217;<a href="http://www.apple.com/fr/iphone/apps-for-iphone/">AppStore</a>, nous avons changé le réglage pour pointer sur l&#8217;API de &#8220;production&#8221;, mais nous avons oublié d&#8217;enlever les en-têtes d&#8217;authentification.<br />
On ne s&#8217;en est pas rendu compte car le serveur de production les ignorait. Il n&#8217;en attendait pas donc peu importe, il laissait tout passer.</p>
<p>Maintenant que les URL des images sont chez Amazon S3, et plus chez nous, ce sont leurs serveurs qui reçoivent les informations d&#8217;authentification. Manque de bol, leur serveur HTTP n&#8217;aime pas du tout les authentification de type HTTP Basic et il renvoi systématiquement une erreur <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">400 (Bad Request)</a>. Le contenu de la réponse est quant à lui une  portion XML indiquant plus d&#8217;infos sur la requête, et c&#8217;est probablement ça qui fait planter l&#8217;appli. La <a href="http://allseeing-i.com/ASIHTTPRequest/">librairie</a> utilisée n&#8217;arrive probablement pas à gérer un contenu XML au lieu d&#8217;un contenu image.</p>
<p>Corriger l&#8217;appli iPhone pour supprimer l&#8217;authentification est très simple, mais il faut ensuite soumettre une nouvelle version à Apple (plusieurs jours de délai pour la valider) puis attendre que l&#8217;extrême majorité de nos utilisateurs mettent à jour l&#8217;appli, … Ce délai n&#8217;était pas envisageable.</p>
<h3>La solution</h3>
<p>Il m&#8217;est donc venue l&#8217;idée bizarre de mettre en place un moyen d&#8217;intercepter les URL demandées par l&#8217;iPhone, de les nettoyer des en-têtes d&#8217;authentification et de les transmettre à Amazon S3.</p>
<p>La mise en œuvre a été simple et rapide (grâce à l&#8217;aide de <a href="http://gcolpart.evolix.net/">Grégory Colpart</a> de <a href="http://evolix.fr">Evolix</a>). Nous avons créé un VirtualHost Apache sur un sous-domaine, dans lequel nous avons paramétré un <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy_http.html">reverse proxy</a>. Toutes les requêtes envoyées à ce sous-domaines sont transmises de manière transparent à Amazon S3, et la directive <a href="http://httpd.apache.org/docs/2.2/mod/mod_headers.html#requestheader">RequestHeader</a> supprime les en-têtes d&#8217;authentification.</p>
<p>Voilà la config du VirtualHost :</p>
<pre><code>    &lt;VirtualHost *:80&gt;
      ServerAdmin webmaster@example.com
      ServerName s3tmp.example.com

      ProxyRequests Off
      &lt;Proxy *&gt;
        Order deny,allow
        Allow from all
      &lt;/Proxy&gt;  

      ProxyPass / http://s3.example.com/
      ProxyPassReverse / http://s3.example.com/

      RequestHeader unset authorization
    &lt;/VirtualHost&gt;
</code></pre>
<p>NB : &#8220;s3tmp.example.com&#8221; est le sous-domaine du proxy, &#8220;s3.example.com&#8221; est un alias vers Amazon S3</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/amazon/'>amazon</a>, <a href='http://jeremy.wordpress.com/tag/apache/'>apache</a>, <a href='http://jeremy.wordpress.com/tag/hotelhotel/'>hotelhotel</a>, <a href='http://jeremy.wordpress.com/tag/iphone/'>iphone</a>, <a href='http://jeremy.wordpress.com/tag/proxy/'>proxy</a>, <a href='http://jeremy.wordpress.com/tag/s3/'>s3</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/327/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/327/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/327/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=327&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2011/01/21/un-proxy-qui-annule-authentification-pourquoi-pas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>grep, cut, awk et compagnie</title>
		<link>http://jeremy.wordpress.com/2011/01/06/grep-cut-awk-et-compagnie/</link>
		<comments>http://jeremy.wordpress.com/2011/01/06/grep-cut-awk-et-compagnie/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 10:58:53 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[PLUG]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=321</guid>
		<description><![CDATA[C&#8217;est vraiment puissant et agréable d&#8217;utiliser des systèmes Linux/Unix. Voilà un nouvel exemple que je veux partager. Contexte Je souhaite quantifier le volume d&#8217;images transférées depuis un de mes serveurs. Le meilleur endroit pour trouver cette info me semble être les fichiers de logs d&#8217;Apache (ou autre serveur web) puisqu&#8217;ils indiquent l&#8217;URL demandée, le code [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=321&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>C&#8217;est vraiment puissant et agréable d&#8217;utiliser des systèmes Linux/Unix. Voilà un nouvel exemple que je veux partager.</p>
<h3>Contexte</h3>
<p>Je souhaite quantifier le volume d&#8217;images transférées depuis un de mes serveurs. Le meilleur endroit pour trouver cette info me semble être les fichiers de logs d&#8217;Apache (ou autre serveur web) puisqu&#8217;ils indiquent l&#8217;URL demandée, le code HTTP et la taille du fichier transmis.</p>
<p>Une fois isolés les logs que je souhaite analyser, il ne me restait plus qu&#8217;à extraire les bons chiffres et en faire une somme.</p>
<h3>Solution</h3>
<p><code>grep '/system' * | grep -o -E '\b200 [0-9]+\b' | cut -f 2 -d ' ' | awk '{sum+=$0} END{print sum/1024/1024}'</code><br />
Je vous décortique chaque étape du processus, séparées par le &#8220;pipe&#8221; (tuyau) qui sert à transmettre le résultat d&#8217;une commande à la suivante.</p>
<p><strong>grep &#8216;/system&#8217; *</strong></p>
<p><tt>grep</tt> permet de lire le contenu d&#8217;un fichier ou d&#8217;un flux et d&#8217;en extraire des parties, selon des règles et filtres. Je lui demande donc de lire tous les fichiers logs (le * à la fin), à la recherche de &#8220;/system&#8221; (la base des URLs qui m&#8217;intéressent).</p>
<p>J&#8217;obtiens donc toutes les lignes de log où une URL qui contient &#8220;/system&#8221; a été demandée.</p>
<p>Exemple :</p>
<p><code>178.48.252.123 - - [12/Dec/2010:07:12:11 +0100] "GET /system/images/missing-sq128.jpg HTTP/1.1" 200 2237 "http://www.hotelhotel.com/stylesheets/hh.css?1291888120" "Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12"</code></p>
<p><strong>grep -o -E &#8216;\b200 [0-9]+\b&#8217;</strong></p>
<p>Les lignes sont analysées une nouvelle fois avec <tt>grep</tt> à la recherche d&#8217;une expression régulière qui permettra d&#8217;isoler les requêtes soldées par un code HTTP 200, indiquant que l&#8217;image a été effectivement téléchargée.</p>
<p>On utilise l&#8217;option <tt>-E</tt> pour indiquer qu&#8217;on veut les expressions régulières &#8220;étendues&#8221;. L&#8217;option <tt>-o</tt> indique qu&#8217;on ne veut renvoyer que ce qui a été capturé par l&#8217;expression, et pas tout la ligne.</p>
<p>L&#8217;expression indique qu&#8217;on souhaite capturer ce qui commence par &#8220;200&#8243;, précédé d&#8217;une rupture de mot (donc un espace, une ponctuation, …), puis un espace, une suite de chiffres, et une rupture de mot.</p>
<p>Exemple :<br />
<code>200 2237</code></p>
<p><strong>cut -f 2 -d &#8216; &#8216;</strong></p>
<p>cut permet de découper la chaîne de caractère et de renvoyer seulement certaines portions de cette chaîne.</p>
<p>L&#8217;option <tt>-d</tt> on indique qu&#8217;on veut découper selon les espaces. L&#8217;option <tt>-f</tt> indique qu&#8217;on veut renvoyer le 2ème segment (la taille de l&#8217;image)</p>
<p>Exemple :<br />
<code>2237</code></p>
<p>À ce stade, on obtient une série de ligne qui contiennent les tailles des images téléchargées, il reste à en faire la somme</p>
<p><strong>awk &#8216;{sum+=$0} END{print sum/1024/1024}&#8217;</strong></p>
<p><tt>awk</tt> est un outil aussi génial que les autres utilisés ici, mais je le connais très mal. C&#8217;est <a href="http://twitter.com/colinux">Colin</a> qui m&#8217;a proposé cette dernière commande.</p>
<p>On demande donc à awk de faire la somme des valeurs trouvées à chaque ligne, de renvoyer cette somme, préalablement convertie en mega-octets (dans les logs Apache, ce sont des octets)</p>
<h3>Conclusion</h3>
<p>J&#8217;ai donc pu faire des opérations pas trop complexes, mais pas non plus triviales, en une seule ligne et avec un résultat immédiat.</p>
<p>Encore fois, ça prouve que bien connaître ses outils permet de travailler efficacement.</p>
<p>Inutile de dire que j&#8217;ai passé plus de temps à écrire ce petit article que pour construire cet enchaînement de commande, avec tous les essais/erreurs.</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/cli/'>cli</a>, <a href='http://jeremy.wordpress.com/tag/linux/'>linux</a>, <a href='http://jeremy.wordpress.com/tag/unix/'>unix</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/321/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/321/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/321/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=321&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2011/01/06/grep-cut-awk-et-compagnie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>Lancement d&#8217;HotelHotel.com</title>
		<link>http://jeremy.wordpress.com/2010/10/07/lancement-hotelhotel-com/</link>
		<comments>http://jeremy.wordpress.com/2010/10/07/lancement-hotelhotel-com/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 10:07:26 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Autrement]]></category>
		<category><![CDATA[autrement]]></category>
		<category><![CDATA[hotel]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=318</guid>
		<description><![CDATA[Et voilà c&#8217;est le jour J Après des mois de travail pour toute une équipe et un premier prototype (Wishbed pour ceux qui l&#8217;ont connu et essayé), Hotel Hotel fait sa sortie au monde ;-) Le but est double : proposer une recherche d&#8217;hôtel en ligne différente : plus d&#8217;hôtels sous la main, plus de [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=318&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Et voilà c&#8217;est le jour J</p>
<p>Après des mois de travail pour toute une équipe et un premier prototype (Wishbed pour ceux qui l&#8217;ont connu et essayé), <strong><a href="http://www.hotelhotel.com/">Hotel Hotel</a></strong> fait sa sortie au monde ;-)</p>
<p>Le but est double :</p>
<ol>
<li>proposer une recherche d&#8217;hôtel en ligne différente : plus d&#8217;hôtels sous la main, plus de chambres disponibles et les meilleurs prix.</li>
<li>apporter une information plus riche sur des destinations choisies : articles sur les villes, analyses complètes de ce qui se dit sur les hôtels (points positifs et négatifs, …)</li>
</ol>
<p>C&#8217;est une première version. On a mille idées géniales à suivre, mais on ne voulait pas attendre plus longtemps pour bouleverser l&#8217;existant.</p>
<p>Faites le tour, essayez le, et surtout réserver des chambres d&#8217;hôtels. Vous verrez qu&#8217;on va vraiment vous aider à réduire vos frais d&#8217;hôtels !</p>
<p>Allez donc découvrir cette première version sur <a href="http://www.hotelhotel.com/">HotelHotel.com</a>.</p>
<p>Vous nous trouverez aussi sur <a href="http://twitter.com/HotelHotel/">Twitter</a> et sur <a href="http://www.facebook.com/pages/HotelHotel/147170755300867">Facebook</a>.</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/autrement-2/'>autrement</a>, <a href='http://jeremy.wordpress.com/tag/hotel/'>hotel</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/318/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=318&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2010/10/07/lancement-hotelhotel-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>L&#8217;équipe technique Autrement cherche 1 ou 2 stagiaires</title>
		<link>http://jeremy.wordpress.com/2010/10/01/lequipe-technique-autrement-cherche-1-ou-2-stagiaires/</link>
		<comments>http://jeremy.wordpress.com/2010/10/01/lequipe-technique-autrement-cherche-1-ou-2-stagiaires/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 15:29:21 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[autrement]]></category>
		<category><![CDATA[stage]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=314</guid>
		<description><![CDATA[Chez Autrement, on cherche 1 ou 2 stagiaires pour faire les alpha-geeks dans l&#8217;équipe technique pendant quelques mois =&#62; http://gist.github.com/606338 Tagged: autrement, stage<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=314&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Chez <a href="http://twitter.com/Autrement">Autrement</a>, on cherche 1 ou 2 stagiaires pour faire les alpha-geeks dans l&#8217;équipe technique pendant quelques mois =&gt; <a href="http://gist.github.com/606338">http://gist.github.com/606338</a></p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/autrement-2/'>autrement</a>, <a href='http://jeremy.wordpress.com/tag/stage/'>stage</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/314/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=314&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2010/10/01/lequipe-technique-autrement-cherche-1-ou-2-stagiaires/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
		<item>
		<title>Assignment-like methods and the returned value (in Ruby)</title>
		<link>http://jeremy.wordpress.com/2010/09/03/assignment-like-methods-and-the-returned-value-in-ruby/</link>
		<comments>http://jeremy.wordpress.com/2010/09/03/assignment-like-methods-and-the-returned-value-in-ruby/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 11:33:21 +0000</pubDate>
		<dc:creator>Jérémy Lecour</dc:creator>
				<category><![CDATA[Informatique]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jeremy.wordpress.com/?p=308</guid>
		<description><![CDATA[An assignment-like method in Ruby always return the Right-Hand Side of the method (the parameter) and never the result of the method. I've learnt this the hard way.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=308&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In Ruby, when you create a class with some instance variable, you usually want to have some ways to get or set the content of those variables, because you can&#8217;t acess them from outside the instance.</p>
<p>If you don&#8217;t know about <strong>attr_accessor</strong> you&#8217;d define a getter and a setter :</p>
<p><pre class="brush: ruby;">
class Foo
  def initialize(name = nil)
    self.name = name
  end
  def name
    @name
  end
  def name=(value)
    @name = value
  end
end
</pre></p>
<p>But you can do this in a much more concise way, like this</p>
<p><pre class="brush: ruby;">
class Foo
  attr_accessor :name

  def initialize(name = nil)
    self.name = name
  end
end
</pre></p>
<p>With both approches, you can do this :</p>
<p><pre class="brush: ruby;">
foo = Foo.new('Jérémy Lecour')
foo.name
#=&gt; &quot;Jérémy Lecour&quot;
foo.name = 'John Appleseed'
#=&gt; &quot;John Appleseed&quot;
</pre></p>
<p>You can dig a little deeper and get to know <strong>attr_reader</strong> and <strong>attr_writer</strong> to make only the getter or only the setter methods. The <a href="http://www.ruby-doc.org/core/classes/Module.html#M001681">official documentation</a> is the first place to be.</p>
<p>Well, that&#8217;s very good, predictable, … but as it happens, I needed to do something a little different and I&#8217;ve hit the wall.</p>
<p>I needed to apply some type casting on the values passed to the setter methods.</p>
<p>So I redefined the method for some attributes on my model. Let&#8217;s say I want to have my name capitalized :</p>
<p><pre class="brush: ruby;">
class Foo
  attr_reader :name

  def initialize(name = nil)
    self.name = name
  end
  def name=(value)
    @name = value.upcase
  end
end
</pre></p>
<p>But I&#8217;ve seen something that I didn&#8217;t expect :</p>
<p><pre class="brush: ruby;">
foo = Foo.new('Jérémy Lecour')
foo.name
#=&gt; &quot;JÉRÉMY LECOUR&quot;
foo.name = 'John Appleseed'
#=&gt; &quot;John Appleseed&quot;
</pre></p>
<p>That&#8217;s right, the setter method return the original value, not the implicit &#8220;return&#8221; that should (says me) return the capitalized verison of the parameter.</p>
<p>I&#8217;ve tried to change alittle bit and tried this :</p>
<p><pre class="brush: ruby;">
class Foo
  attr_reader :name

  def initialize(name = nil)
    self.set_name name
  end
  def set_name(value)
    @name = value.upcase
  end
end

foo = Foo.new('Jérémy Lecour')
foo.name
#=&gt; &quot;JÉRÉMY LECOUR&quot;
</pre></p>
<p>OK, that&#8217;s weird, the name of the method make the method behave differently, even if the &#8220;content&#8221; of the method is exactly the same.</p>
<p>With a little enlightment from the #ruby-lang people on IRC, I&#8217;ve learnt the concept of RHS (Right-Hand Side).</p>
<p>If you define an &#8220;assignment-like&#8221; method (with an equal sign at the end), Ruby will execute the method when you call it, but will always return the supplied parameter and never the result of the method.</p>
<p>As a result you can&#8217;t chain those methods, but it&#8217;s actually a good thing. For example :</p>
<p><pre class="brush: ruby;">
foo = Foo.new()
bar = foo.name = 'John Doe'
foo.name
#=&gt; &quot;JOHN DOE&quot;
bar
#=&gt; &quot;John Doe&quot;
</pre></p>
<p>And by only reading the chained assignments, the result would not be obvious.</p>
<p>The lesson here has 2 points :<br />
- you <strong>can&#8217;t chain assignent-like methods</strong>, so if you need such a thing, do it differently<br />
- <strong>it is not a bug, it is a feature</strong>, and actually a good one when you understand the stakes</p>
<p>This has eaten at least 3 hours yesterday, so I thought it might benefit someone else.</p>
<br /> Tagged: <a href='http://jeremy.wordpress.com/tag/ruby/'>ruby</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremy.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremy.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremy.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremy.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremy.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremy.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremy.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremy.wordpress.com/308/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremy.wordpress.com&amp;blog=430&amp;post=308&amp;subd=jeremy&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremy.wordpress.com/2010/09/03/assignment-like-methods-and-the-returned-value-in-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7d1caf9df777b3b2cf474ff743494335?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">jeremy</media:title>
		</media:content>
	</item>
	</channel>
</rss>
