<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Damien Krotkine</title>
 
 <link href="http://dams.github.com/" />
 <updated>2013-02-11T23:52:46-08:00</updated>
 <id>http://dams.github.com/</id>
 <author>
   <name>Damien Krotkine</name>
   <email>dams@zarb.org</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/damien-krotkine" /><feedburner:info uri="damien-krotkine" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>MooX::LvalueAttribute - Lvalue accessors in Moo</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/puEL1U3tQFY/lvalue-accessors-in-moo.html" />
   <updated>2013-02-11T00:00:00-08:00</updated>
   <id>http://dams.github.com/2013/02/11/lvalue-accessors-in-moo</id>
   <content type="html">&lt;h1 id='mooxlvalueattribute__lvalue_accessors_in_moo'&gt;MooX::LvalueAttribute - Lvalue accessors in Moo&lt;/h1&gt;

&lt;p&gt;Yesterday I was reading &lt;a href='http://blogs.perl.org/users/joel_berger/2013/02/in-the-name-of-create-great-things-in-perl.html'&gt;Joel&amp;#8217;s post&lt;/a&gt;, where he lists great Perl things he&amp;#8217;s seen done lately. Indeed these are great stuff. I was particulary interested by his try at playing with &lt;a href='https://gist.github.com/jberger/4740303'&gt;Lvalue accessors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I thought that it would be a great exercise to try to implement it in Moo, as an additional feature, trying to get rid of the &lt;code&gt;AUTOLOAD&lt;/code&gt;. Also, I was willing to avoid doing a &lt;code&gt;tie&lt;/code&gt; every time an instance attribute accessor was called. Surely, I needed to tie only &lt;em&gt;once&lt;/em&gt; per instance and per attribute, not each time the attribute is accessed.&lt;/p&gt;

&lt;p&gt;So I started hacking on the code of Moo. Getting rid of the AUTOLOAD was easy, as I could change the way the accessor generator was, well, generating the, err, accessors.&lt;/p&gt;

&lt;p&gt;Shortly after I started having issues to cache a tied variable. I asked the all-mighty &lt;a href='https://metacpan.org/author/VPIT'&gt;Vincent Pit&lt;/a&gt;, and he found a solution for my tied variables, but more importanlty pointed me to &lt;a href='https://metacpan.org/module/Variable::Magic'&gt;Variable::Magic&lt;/a&gt;, which is faster, more flexible and powerful.&lt;/p&gt;

&lt;p&gt;All I needed was to move my hacks in a proper Role, and wrap the whole in a module, and push it on CPAN. Tadaa, &lt;a href='https://metacpan.org/module/MooX::LvalueAttribute'&gt;MooX::LvalueAttribute&lt;/a&gt; was born.&lt;/p&gt;

&lt;p&gt;In the process I used &lt;a href='http://play-perl.org'&gt;play-perl&lt;/a&gt; to register my quests, and exchanged &lt;a href='http://play-perl.org/quest/511800ae94f611130b000025'&gt;thoughts with Joel Berger&lt;/a&gt;. I think I&amp;#8217;m going to use this website more, see if it can boost my productivity, and help me figure out what&amp;#8217;s really important to do.&lt;/p&gt;

&lt;p&gt;On IRC, haarg discovered a bug and recommended to use so-called &lt;em&gt;fieldhashes&lt;/em&gt;, from &lt;a href='https://metacpan.org/module/Hash::Util::FieldHash::Compat'&gt;Hash::Util::FieldHash::Compat&lt;/a&gt;. At the end of the day, I only acted as a glue between different pieces of knowledges, and that was very satisfactory.&lt;/p&gt;

&lt;h2 id='tldr'&gt;TL:DR&lt;/h2&gt;

&lt;p&gt;&lt;a href='https://metacpan.org/module/MooX::LvalueAttribute'&gt;MooX::LvalueAttribute&lt;/a&gt; is a module that provides Lvalue attributes:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='nb'&gt;package&lt;/span&gt; &lt;span class='n'&gt;App&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='n'&gt;Moo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;MooX::&lt;/span&gt;&lt;span class='n'&gt;LvalueAttribute&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;
  &lt;span class='n'&gt;is&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;rw&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='n'&gt;lvalue&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='c1'&gt;# Elsewhere&lt;/span&gt;
&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$app&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;App&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='nv'&gt;$app&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;print&lt;/span&gt; &lt;span class='nv'&gt;$app&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;  &lt;span class='c1'&gt;# Bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/puEL1U3tQFY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2013/02/11/lvalue-accessors-in-moo.html</feedburner:origLink></entry>
 
 <entry>
   <title>New Perl module: Action::Retry</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/3NdCPjmni6U/new-module-actionretry.html" />
   <updated>2013-01-21T00:00:00-08:00</updated>
   <id>http://dams.github.com/2013/01/21/new-module-actionretry</id>
   <content type="html">&lt;h1 id='new_perl_module_actionretry'&gt;New Perl module: Action::Retry&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;UPDATE: I have included a functional API, as per Oleg Komarov request, and amended this post accordingly&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve just released a new module called &lt;a href='https://metacpan.org/module/Action::Retry'&gt;Action::Retry&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Use it when you want to run some code until it succeeds, waiting between two retries.&lt;/p&gt;

&lt;p&gt;A simple way to use it is :&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Action::&lt;/span&gt;&lt;span class='n'&gt;Retry&lt;/span&gt; &lt;span class='sx'&gt;qw(retry)&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='n'&gt;retry&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the Object Oriented API:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='nn'&gt;Action::&lt;/span&gt;&lt;span class='n'&gt;Retry&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='n'&gt;attempt_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The purpose of this module is similar to &lt;code&gt;Retry&lt;/code&gt;, &lt;code&gt;Sub::Retry&lt;/code&gt;, &lt;code&gt;Attempt&lt;/code&gt; and &lt;code&gt;AnyEvent::Retry&lt;/code&gt;. However, it&amp;#8217;s highly configurable, more flexible and has more features.&lt;/p&gt;

&lt;p&gt;You can specify the code to try, but also a callback that will be executed to check the success or failure of the attempt. There is also a callback to execute code on failure.&lt;/p&gt;

&lt;p&gt;The module also supports different sleep strategies ( Constant, Linear, Fibonacci&amp;#8230;) and it&amp;#8217;s easy to build yours. Strategies can have their options as well.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$action&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nn'&gt;Action::&lt;/span&gt;&lt;span class='n'&gt;Retry&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
  &lt;span class='n'&gt;attempt_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='n'&gt;retry_if_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nv'&gt;$_&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt;&lt;span class='sr'&gt; /Connection lost/&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='nv'&gt;$_&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;20&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='n'&gt;strategy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;Fibonacci&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;multiplicator&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;2000&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                               &lt;span class='n'&gt;initial_term_index&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                               &lt;span class='n'&gt;max_retries_number&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                             &lt;span class='p'&gt;}&lt;/span&gt;
              &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='n'&gt;on_failure_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;say&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Given up retrying&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nv'&gt;$action&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the functional API:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;  &lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Action::&lt;/span&gt;&lt;span class='n'&gt;Retry&lt;/span&gt; &lt;span class='sx'&gt;qw(retry)&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='n'&gt;retry&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='n'&gt;retry_if_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nv'&gt;$_&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt;&lt;span class='sr'&gt; /Connection lost/&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='nv'&gt;$_&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;20&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='n'&gt;strategy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;Fibonacci&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;multiplicator&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;2000&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                               &lt;span class='n'&gt;initial_term_index&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                               &lt;span class='n'&gt;max_retries_number&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                             &lt;span class='p'&gt;}&lt;/span&gt;
              &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='n'&gt;on_failure_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;say&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Given up retrying&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Strategies can decide if it&amp;#8217;s worthwhile continuing trying, or if it should fail.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://metacpan.org/module/Action::Retry'&gt;Action::Retry&lt;/a&gt; also supports a pseudo &amp;#8220;non-blocking&amp;#8221; mode, in which it doesn&amp;#8217;t actually sleep, but instead returns immediately, and won&amp;#8217;t perform the action code until required time has elapsed. Basicaly it allows to do this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$action&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nn'&gt;Action::&lt;/span&gt;&lt;span class='n'&gt;Retry&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
  &lt;span class='n'&gt;attempt_code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='n'&gt;non_blocking&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='n'&gt;strategy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Constant&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;# if the action failed, it doesn&amp;#39;t sleep&lt;/span&gt;
  &lt;span class='c1'&gt;# next time it&amp;#39;s called, it won&amp;#39;t do anything until it&amp;#39;s time to retry&lt;/span&gt;
  &lt;span class='nv'&gt;$action&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;run&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;

  &lt;span class='n'&gt;do_something_else&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='c1'&gt;# do something else while time goes on&lt;/span&gt;

&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;of course &lt;code&gt;do_something_else&lt;/code&gt; should be very fast, so that the loop goes back quickly to retrying the &lt;code&gt;attempt_code&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://metacpan.org/module/Action::Retry'&gt;Action::Retry&lt;/a&gt; is based on &lt;a href='https://metacpan.org/module/Moo'&gt;Moo&lt;/a&gt; for performance (and because the module is simple enough to not require Moose). Moo classes properly expand to Moose ones if needed, so there is no excuse not to use it.&lt;/p&gt;

&lt;p&gt;So, please give a try to &lt;a href='https://metacpan.org/module/Action::Retry'&gt;Action::Retry&lt;/a&gt;, and let me know what you think.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/3NdCPjmni6U" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2013/01/21/new-module-actionretry.html</feedburner:origLink></entry>
 
 <entry>
   <title>Mass-Testing Dancer's Plugins</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/rUr97LrUcxs/masstesting-dancers-plugins.html" />
   <updated>2012-09-20T00:00:00-07:00</updated>
   <id>http://dams.github.com/2012/09/20/masstesting-dancers-plugins</id>
   <content type="html">&lt;h1 id='masstesting_dancers_plugins'&gt;Mass-Testing Dancer&amp;#8217;s Plugins&lt;/h1&gt;

&lt;p&gt;So, as I said at YAPC::EU 2012, one thing that remains to be done before Dancer 2 can be released : migrating the plugins, making sure they work with it.&lt;/p&gt;

&lt;p&gt;To be able to do that, what&amp;#8217;s best than an automatic testing facility ?&lt;/p&gt;

&lt;p&gt;The goal is to get all Dancer plugins, test them with Dancer1, and Dancer2, and produce a report, to check which one fails and need fixing.&lt;/p&gt;

&lt;h2 id='step_1_get_the_list_of_dancer_plugins'&gt;Step 1. Get the list of Dancer plugins.&lt;/h2&gt;

&lt;p&gt;Easy ! let&amp;#8217;s use &lt;a href='https://metacpan.org/'&gt;Metacpan&lt;/a&gt;. After searching, I finally got a way to get the list of all modules that depend on Dancer. Then filtering out the ones that don&amp;#8217;t contain &lt;code&gt;&amp;quot;Plugin&amp;quot;&lt;/code&gt; will do the trick.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='c1'&gt;#!/usr/bin/env perl&lt;/span&gt;

&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Modern::&lt;/span&gt;&lt;span class='n'&gt;Perl&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='n'&gt;ElasticSearch&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$es&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ElasticSearch&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='n'&gt;servers&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;api.metacpan.org&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;no_refresh&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$scroller&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$es&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;scrolled_search&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
    &lt;span class='n'&gt;query&lt;/span&gt;       &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;match_all&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='n'&gt;search_type&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;scan&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='n'&gt;scroll&lt;/span&gt;      &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;5m&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='nb'&gt;index&lt;/span&gt;       &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;v0&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='n'&gt;type&lt;/span&gt;        &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;release&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='n'&gt;size&lt;/span&gt;        &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='n'&gt;filter&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;term&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
                     &lt;span class='s'&gt;&amp;#39;release.dependency.module&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Dancer&amp;#39;&lt;/span&gt;
                    &lt;span class='p'&gt;}&lt;/span&gt;
              &lt;span class='p'&gt;},&lt;/span&gt;

&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$result&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$scroller&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;next&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;%plugins&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$result&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$scroller&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;next&lt;/span&gt; &lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nv'&gt;$result&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;_source&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt;&lt;span class='sr'&gt; /Dancer-Plugin/&lt;/span&gt;
      &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='k'&gt;next&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$name&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$result&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;_source&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;
    &lt;span class='nv'&gt;$name&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='sr'&gt;s/-\d.*//&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nv'&gt;$name&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='sr'&gt;s/-/::/g&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nv'&gt;$plugins&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nv'&gt;$name&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='n'&gt;say&lt;/span&gt; &lt;span class='nv'&gt;$_&lt;/span&gt; &lt;span class='k'&gt;foreach&lt;/span&gt; &lt;span class='nb'&gt;sort&lt;/span&gt; &lt;span class='nb'&gt;keys&lt;/span&gt; &lt;span class='nv'&gt;%plugins&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cool, let&amp;#8217;s save this script as &lt;code&gt;get_modules_list.pl&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='step_2_prepare_two_perl_environments'&gt;Step 2. Prepare two Perl environments&lt;/h2&gt;

&lt;p&gt;We want two instance of Perl, without polluting anything. We&amp;#8217;ll use &lt;a href='http://www.perlbrew.pl/'&gt;perlbrew&lt;/a&gt; for that. Easy. The small trick is to have &lt;code&gt;PERLBREW_ROOT&lt;/code&gt; initialized to a local directory to not polute existing &lt;code&gt;~/perl5&lt;/code&gt; installation.&lt;/p&gt;

&lt;h2 id='step_3_have_a_way_to_test_modules'&gt;Step 3. Have a way to test modules&lt;/h2&gt;

&lt;p&gt;Well, let&amp;#8217;s use &lt;a href='http://cpanmin.us/'&gt;cpanm&lt;/a&gt;, which has an option &lt;code&gt;--test-only&lt;/code&gt; to only test a module without installing it. Oh but plugin modules that we&amp;#8217;ll test may require dependances. We&amp;#8217;ll install them using &lt;code&gt;cpanm --installdeps&lt;/code&gt;, which does just that.&lt;/p&gt;

&lt;h2 id='step_4_create_a_result_file'&gt;Step 4. Create a result file&lt;/h2&gt;

&lt;p&gt;I was lazy and just output to a &lt;code&gt;.csv&lt;/code&gt; text file, but I may store the results somewhere else later.&lt;/p&gt;

&lt;h2 id='step_5_lets_glue_all_that_in_a_makefile'&gt;Step 5. Let&amp;#8217;s glue all that in a Makefile&lt;/h2&gt;

&lt;p&gt;The beauty of this is that by writing a proper Makefile, we can install this auto-tester anywhere. The requirements are minimal : &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, and &lt;code&gt;perl&lt;/code&gt;, with &lt;code&gt;ElasticSearch&lt;/code&gt; and &lt;code&gt;Modern::Perl&lt;/code&gt; installed.&lt;/p&gt;

&lt;p&gt;( This post is intentionally named the same as &lt;a href='http://babyl.dyndns.org/techblog/entry/test-dancer-plugins'&gt;the one from Yannick&lt;/a&gt;, because he proposed a different implementation. We&amp;#8217;ll try to merge the good ideas together )&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;HERE&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PWD&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;

&lt;span class='c'&gt;# set up the local Perlbrew location&lt;/span&gt;
&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;HERE&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/perlbrew
&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nb'&gt;export &lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_ROOT&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; &lt;span class='se'&gt;\&lt;/span&gt;
    &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nb'&gt;source&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/etc/bashrc &lt;span class='se'&gt;\&lt;/span&gt;
    &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nv'&gt;PERLBREW_ROOT&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/perlbrew

&lt;span class='c'&gt;# This will run the cpanm from the local Perlbrew, on each of the 2 perls&lt;/span&gt;
&lt;span class='nv'&gt;CPANM_DANCER1&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; &lt;span class='nb'&gt;exec&lt;/span&gt; --with dancer1_plugin_tests &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/cpanm
&lt;span class='nv'&gt;CPANM_DANCER2&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; &lt;span class='nb'&gt;exec&lt;/span&gt; --with dancer2_plugin_tests &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/cpanm

&lt;span class='c'&gt;# loop on the plugin list, install the deps and test each plugin and output result&lt;/span&gt;
all: got_curl got_bash got_perlbrew_perl plugins_list
	&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Plugin name,Pass on Dancer 1,Pass on Dancer 2&amp;quot;&lt;/span&gt; &amp;gt; result.csv
	@for i in &lt;span class='sb'&gt;`&lt;/span&gt;cat plugins_list&lt;span class='sb'&gt;`&lt;/span&gt;; &lt;span class='k'&gt;do &lt;/span&gt;&lt;span class='nv'&gt;pass_d1&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;0; &lt;span class='nv'&gt;pass_d2&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;0; &lt;span class='se'&gt;\&lt;/span&gt;
	  &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; ---------- TESTING on Dancer 1 : $$i&amp;quot;&lt;/span&gt;; &lt;span class='se'&gt;\&lt;/span&gt;
          &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;CPANM_DANCER1&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; -n --installdeps &lt;span class='nv'&gt;$$&lt;/span&gt;i &lt;span class='se'&gt;\&lt;/span&gt;
              &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;CPANM_DANCER1&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; --test-only &lt;span class='nv'&gt;$$&lt;/span&gt;i &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nv'&gt;pass_d1&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;1; &lt;span class='se'&gt;\&lt;/span&gt;
	  &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; ---------- TESTING on Dancer 2 : $$i&amp;quot;&lt;/span&gt;; &lt;span class='se'&gt;\&lt;/span&gt;
          &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;CPANM_DANCER2&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; -n --installdeps &lt;span class='nv'&gt;$$&lt;/span&gt;i &lt;span class='se'&gt;\&lt;/span&gt;
              &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nv'&gt;DANCER_FORCE_PLUGIN_REGISTRATION&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;1 &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;CPANM_DANCER2&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; --test-only &lt;span class='nv'&gt;$$&lt;/span&gt;i &lt;span class='se'&gt;\&lt;/span&gt;
              &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nv'&gt;pass_d2&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;1; &lt;span class='se'&gt;\&lt;/span&gt;
          &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;$$i,$$pass_d1,$$pass_d2&amp;quot;&lt;/span&gt; &amp;gt;&amp;gt; result.csv; &lt;span class='se'&gt;\&lt;/span&gt;
        &lt;span class='k'&gt;done&lt;/span&gt;;

clean:
	rm -rf plugins_list

fullclean:
	rm -rf &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;

&lt;span class='c'&gt;# Get and install Perlbrew locally&lt;/span&gt;
&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/perlbrew:
	@echo &lt;span class='s2'&gt;&amp;quot; - creating a local perlbrew&amp;quot;&lt;/span&gt;
	&lt;span class='nb'&gt;export &lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_ROOT&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl -kL http://install.perlbrew.pl | bash

&lt;span class='c'&gt;# Get and install cpanm in the local Perlbrew&lt;/span&gt;
&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/cpanm:
	&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; install-cpanm

got_curl:
	@which curl &amp;gt;/dev/null &lt;span class='se'&gt;\&lt;/span&gt;
        &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt; &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;you don&amp;#39;t have curl, please install it and retry&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nb'&gt;false&lt;/span&gt; &lt;span class='o'&gt;)&lt;/span&gt;

got_bash:
	@which bash &amp;gt;/dev/null &lt;span class='se'&gt;\&lt;/span&gt;
        &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt; &lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;you don&amp;#39;t have bash, please install it and retry&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nb'&gt;false&lt;/span&gt; &lt;span class='o'&gt;)&lt;/span&gt;

got_perlbrew_perl: &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/perlbrew &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW_DIR&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/bin/cpanm perlbrew_dancer1_plugin_tests perlbrew_dancer2_plugin_tests

&lt;span class='c'&gt;# Build perl from scratch and call this instance dancer1&lt;/span&gt;
perlbrew_dancer1_plugin_tests:
	&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; list | grep dancer1_plugin_tests &amp;gt; /dev/null &lt;span class='se'&gt;\&lt;/span&gt;
        &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; install -j 2 -n perl-5.16.1 --as dancer1_plugin_tests &lt;span class='o'&gt;)&lt;/span&gt;

&lt;span class='c'&gt;# Build perl from scratch and call this instance dancer2&lt;/span&gt;
perlbrew_dancer2_plugin_tests:
	&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; list | grep dancer2_plugin_tests &amp;gt; /dev/null &lt;span class='se'&gt;\&lt;/span&gt;
        &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;PERLBREW&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; install -j 2 -n perl-5.16.1 --as dancer2_plugin_tests &lt;span class='se'&gt;\&lt;/span&gt;
             &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;CPANM_DANCER2&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt; &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;HERE&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/../.. &lt;span class='o'&gt;)&lt;/span&gt;

&lt;span class='c'&gt;# This gets the list of plugins, as previously described&lt;/span&gt;
plugins_list:
	&lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;HERE&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;/get_modules_list.pl &amp;gt; plugins_list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s really cool to see what you can do with modern tools of the Perl ecosystem !&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/rUr97LrUcxs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/09/20/masstesting-dancers-plugins.html</feedburner:origLink></entry>
 
 <entry>
   <title>Paris.pm technical meeting</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/QcGedPq0xaE/paris-pm-technical-meeting.html" />
   <updated>2012-09-15T00:00:00-07:00</updated>
   <id>http://dams.github.com/2012/09/15/paris-pm-technical-meeting</id>
   <content type="html">&lt;h1 id='parispm_technical_meeting'&gt;Paris.pm technical meeting&lt;/h1&gt;

&lt;p&gt;( french version below )&lt;/p&gt;

&lt;p&gt;The next Paris.pm technical meeting will happen the &lt;strong&gt;25th september 2012&lt;/strong&gt;, with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elizabeth Cholet: Firefox automatization with Perl using AnyEvent, Coro and MozRepl modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt; : 181 avenue Daumesnil, 75012 Paris, France&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google map&lt;/strong&gt; : &lt;a href='http://goo.gl/OGUbI'&gt;google map&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are interested, and live in Paris, please join us ! If you need more info, ask in the comments.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;La prochaine réunion technique de Paris.pm se tiendra mardi &lt;strong&gt;25 septembre 2012&lt;/strong&gt;, et le programme est :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elizabeth Cholet : l&amp;#8217;automatisation de Firefox avec Perl en utilisant AnyEvent, Coro et les modules MozRepl&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adresse&lt;/strong&gt; : 181 avenue Daumesnil, 75012 Paris&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google map&lt;/strong&gt; : &lt;a href='http://goo.gl/OGUbI'&gt;google map&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si vous êtes intéressé, n&amp;#8217;hésitez pas à venir, entrée libre et gratuite. Pour plus d&amp;#8217;info, demandez dans les commentaires.&lt;/p&gt;

&lt;p&gt;dams.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/QcGedPq0xaE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/09/15/paris-pm-technical-meeting.html</feedburner:origLink></entry>
 
 <entry>
   <title>MooseX::Singleton is slow</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/Wxnlo5L25BQ/moosexsingleton-is-slow.html" />
   <updated>2012-07-04T00:00:00-07:00</updated>
   <id>http://dams.github.com/2012/07/04/moosexsingleton-is-slow</id>
   <content type="html">&lt;h1 id='moosexsingleton_is_slow'&gt;MooseX::Singleton is slow&lt;/h1&gt;

&lt;p&gt;Just a quick note : if you plan to use &lt;a href='https://metacpan.org/module/MooseX::Singleton'&gt;MooseX::Singleton&lt;/a&gt;, beware ! It is easy to use and it implements properly what it claims, however it is quite slow.&lt;/p&gt;

&lt;p&gt;If my profilings are corrects, each call to &lt;code&gt;-&amp;gt;instance()&lt;/code&gt; calls &lt;code&gt;meta()&lt;/code&gt;, &lt;code&gt;get_metaclass_by_name()&lt;/code&gt; one time, and &lt;code&gt;blessed()&lt;/code&gt; two times.&lt;/p&gt;

&lt;p&gt;So for now I&amp;#8217;ll avoid it and implement a simplified version using something similar to this :&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='n'&gt;Moose&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$singleton&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;instance&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nv'&gt;$singleton&lt;/span&gt; &lt;span class='sr'&gt;//&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$CLASS&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='c1'&gt;# to protect against people using new() instead of instance()&lt;/span&gt;
&lt;span class='n'&gt;around&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;new&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$orig&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;shift&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$self&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;shift&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nv'&gt;$singleton&lt;/span&gt; &lt;span class='sr'&gt;//&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$self&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='nv'&gt;$orig&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;@_&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;

&lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;initialize&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nb'&gt;defined&lt;/span&gt; &lt;span class='nv'&gt;$singleton&lt;/span&gt;
      &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='n'&gt;__PACKAGE__&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='s'&gt;&amp;#39; singleton has already been instanciated&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; 
    &lt;span class='nb'&gt;shift&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;__PACKAGE__&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;@_&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;dams.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/Wxnlo5L25BQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/07/04/moosexsingleton-is-slow.html</feedburner:origLink></entry>
 
 <entry>
   <title>Dancer is community-driven</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/74H4HvkZaWg/dancer-is-communitydriven.html" />
   <updated>2012-06-20T00:00:00-07:00</updated>
   <id>http://dams.github.com/2012/06/20/dancer-is-communitydriven</id>
   <content type="html">&lt;h1 id='dancer_is_communitydriven'&gt;Dancer is community-driven&lt;/h1&gt;

&lt;p&gt;Long time I haven&amp;#8217;t blogged about Dancer.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.antelink.com/'&gt;Antelink&lt;/a&gt; is a french startup, specializing in Software Life Cycle Management and Open Source Component Detection. They provided us with cool Dancer sourcecode analyzis graphs.&lt;/p&gt;

&lt;h2 id='overall_contribution_by_users'&gt;Overall contribution by users&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts_by_users.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts_by_users.png' height='162' width='376.5' /&gt;&lt;/a&gt;
&lt;h2 id='pm_files_contribution_by_users'&gt;.pm files contribution by users&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts-only_pm-by_users.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts-only_pm-by_users.png' height='150' width='366' /&gt;&lt;/a&gt;
&lt;h2 id='pod_files_contribution_by_users'&gt;Pod files contribution by users&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts-only_pod-by_users.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts-only_pod-by_users.png' height='150' width='366' /&gt;&lt;/a&gt;
&lt;h2 id='test_files_contribution_by_users'&gt;Test files contribution by users&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts-only_t-by_users.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts-only_t-by_users.png' height='150' width='366' /&gt;
&lt;/a&gt;
&lt;h2 id='reading_these_graphs'&gt;Reading these graphs&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;UPDATE&lt;/em&gt; : The surfaces represent a mean between the number of commits, and the weight of modifications contributed (in term of &amp;#8220;code line&amp;#8221;), only when these are original content addition. Moving content around isn&amp;#8217;t counted as active contribution.&lt;/p&gt;

&lt;p&gt;Note that some people are registered twice with different names, I&amp;#8217;ll try to post an updated version&lt;/p&gt;

&lt;p&gt;What does that demonstrate ? It shows that Dancer is &lt;em&gt;really&lt;/em&gt; powered by its community. Decisions are made together, the code is hacked by multiple hands, and the management is done in a collegial manner on github.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a great reward to be visible on these graphs :)&lt;/p&gt;

&lt;h1 id='more_graphs'&gt;More Graphs&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;UPDATE&lt;/em&gt; : Erwan (@Labynocle) sent me new graphics, they show the difference between core devs and contributors. By the ay, Erwan will be at the &lt;a href='http://journeesperl.fr/fpw2012/'&gt;French Perl Workshop&lt;/a&gt; in Strasbourg, France.&lt;/p&gt;

&lt;p&gt;So here we go :&lt;/p&gt;

&lt;h2 id='pm_files_contribution_by_groups'&gt;.pm files contribution by groups&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts-only_pm-by_groups.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts-only_pm-by_groups.png' height='150' width='366' /&gt;&lt;/a&gt;
&lt;h2 id='pod_files_contribution_by_groups'&gt;Pod files contribution by groups&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts-only_pod-by_groups.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts-only_pod-by_groups.png' height='150' width='366' /&gt;&lt;/a&gt;
&lt;h2 id='test_files_contribution_by_groups'&gt;Test files contribution by groups&lt;/h2&gt;
&lt;a href='/images/dancer_analysis_by_Antelink-contribution_parts-only_t-by_groups.png'&gt;
&lt;img src='/images/dancer_analysis_by_Antelink-contribution_parts-only_t-by_groups.png' height='150' width='366' /&gt;
&lt;/a&gt;
&lt;p&gt;As a side note, I&amp;#8217;ve proposed 2 talks related to Dancer for &lt;a href='http://act.yapc.eu/ye2012/'&gt;YAPC::EU&lt;/a&gt;. One called &lt;em&gt;&amp;#8220;Dancer + WebSocket + AnyEvent + Twiggy&amp;#8221;&lt;/em&gt;, and an other one mixing &lt;code&gt;Dancer&lt;/code&gt;, &lt;code&gt;Log::Message::Structured&lt;/code&gt; and &lt;code&gt;Message::Passing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s hope they&amp;#8217;ll get accepted !&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/74H4HvkZaWg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/06/20/dancer-is-communitydriven.html</feedburner:origLink></entry>
 
 <entry>
   <title>Cross Posting to blogs.perl.org</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/ROBK8LFSeko/cross-posting-to-blogsperlorg.html" />
   <updated>2012-04-05T00:00:00-07:00</updated>
   <id>http://dams.github.com/2012/04/05/cross-posting-to-blogsperlorg</id>
   <content type="html">&lt;h1 id='cross_posting_to_blogsperlorg'&gt;Cross Posting to blogs.perl.org&lt;/h1&gt;

&lt;p&gt;So, a while ago, I moved &lt;a href='http://damien.krotkine.com'&gt;my blog&lt;/a&gt; to github, using &lt;a href='https://github.com/mojombo/jekyll'&gt;jekyll&lt;/a&gt; and &lt;a href='http://daringfireball.net/projects/markdown/'&gt;markdown&lt;/a&gt;, with &lt;a href='http://metajack.im/2009/01/02/manage-jekyll-from-emacs/'&gt;jekyll integration&lt;/a&gt; in &lt;a href='http://www.gnu.org/software/emacs/'&gt;Emacs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That works great, and I like the fasct that posting a blog entry is just a regular git push.&lt;/p&gt;

&lt;p&gt;My blog is aggregated in some places, but it doesn&amp;#8217;t appear on &lt;a href='http://blogs.perl.org'&gt;blogs.perl.org&lt;/a&gt;, because it&amp;#8217;s not an aggregator (and that&amp;#8217;s cool, it&amp;#8217;s not its purpose). But, blogs.perl.org audience is big, and I&amp;#8217;m missing all these potential readers (in improbable case people would actually be interested in what I have to say :) )&lt;/p&gt;

&lt;p&gt;Anyway, so I decided to bite the bullet and write a script that would cross post my entry to blogs.perl.org. I made the script generic enough to work with different type of blogs, but here I&amp;#8217;m going to explain only the blogs.perl.org specific case.&lt;/p&gt;

&lt;p&gt;blogs.perl.org is a &lt;a href='http://www.movabletype.org/'&gt;Movable Type&lt;/a&gt; blog engine. A look on &lt;a href='http://metacpan.org'&gt;Metacpan&lt;/a&gt; indicates us there is a &lt;a href='https://metacpan.org/module/Net::MovableType'&gt;Net::MovableType&lt;/a&gt; module. That&amp;#8217;s great, let&amp;#8217;s use that.&lt;/p&gt;

&lt;p&gt;There is a catch: to use this module, you need your login, and your &lt;em&gt;API password&lt;/em&gt;, not your regular password. You can get it easily though, by &lt;a href='https://github.com/davorg/blogs.perl.org/issues/137'&gt;following these instructions&lt;/a&gt; (thanks to davorg for directing me to it).&lt;/p&gt;

&lt;p&gt;To avoid storing the user / password in the script, and to have to pass it on the command line, let&amp;#8217;s have a configuration file, that will lie at &lt;code&gt;~/.crosspost.ini&lt;/code&gt;, and that we&amp;#8217;ll load with &lt;a href='https://metacpan.org/module/Config::Any::Merge'&gt;Config::Any::Merge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The file name of the original post will have to be passed on the command line, using &lt;a href='https://metacpan.org/module/Getopt::Long'&gt;Getopt::Long&lt;/a&gt; and &lt;a href='https://metacpan.org/module/Path::Class'&gt;Path::Class&lt;/a&gt; to retrieve and slurp it.&lt;/p&gt;

&lt;p&gt;Here is the configuration file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# file ~/.corsspost.ini
[ main_blog ]
title = dams blog
url = http://damien.krotkine.com

[ blogs.perl.org ]
type = mt
username = foo
password = bar
url = http://blogs.perl.org/rsd.xml&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And here&amp;#8217;s the code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='c1'&gt;# file crosspost.plcorsspost.ini&lt;/span&gt;

&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Modern::&lt;/span&gt;&lt;span class='n'&gt;Perl&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='n'&gt;Carp&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Net::&lt;/span&gt;&lt;span class='n'&gt;MovableType&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Config::Any::&lt;/span&gt;&lt;span class='n'&gt;Merge&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Getopt::&lt;/span&gt;&lt;span class='n'&gt;Long&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Path::&lt;/span&gt;&lt;span class='n'&gt;Class&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Text::&lt;/span&gt;&lt;span class='n'&gt;Markdown&lt;/span&gt; &lt;span class='sx'&gt;qw(markdown)&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$file&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='n'&gt;GetOptions&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;file=s&amp;quot;&lt;/span&gt;   &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;\&lt;/span&gt;&lt;span class='nv'&gt;$file&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;failed to parse command line options&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='nv'&gt;$file&lt;/span&gt;
  &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;need a file&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='nv'&gt;$file&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$file&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='c1'&gt;# Get a hash representing the config file&lt;/span&gt;
&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$cfg&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;values&lt;/span&gt; &lt;span class='nv'&gt;%&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nn'&gt;Config::&lt;/span&gt;&lt;span class='n'&gt;Any&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;load_files&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='n'&gt;files&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt; &lt;span class='nv'&gt;$ENV&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;HOME&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;/.crosspost.ini&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='n'&gt;use_ext&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='p'&gt;})&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]})[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;

&lt;span class='c1'&gt;# Grab some main info&lt;/span&gt;
&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$main_blog_title&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$cfg&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;main_blog&lt;/span&gt;&lt;span class='p'&gt;}{&lt;/span&gt;&lt;span class='n'&gt;title&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$main_blog_url&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$cfg&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;main_blog&lt;/span&gt;&lt;span class='p'&gt;}{&lt;/span&gt;&lt;span class='n'&gt;url&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;

&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$text&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$file&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;slurp&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='c1'&gt;# In reality, I do some transformation on $text to interpret jekyll specific&lt;/span&gt;
&lt;span class='c1'&gt;# syntax&lt;/span&gt;

&lt;span class='nv'&gt;$text&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;\n &amp;lt;i&amp;gt;cross-posted from [$main_blog_title]($main_blog_url)&amp;lt;/i&amp;gt;\n\n&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$text&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

&lt;span class='c1'&gt;# So now we have the content to be posted, but it&amp;#39;s in markdown. Let&amp;#39;s&lt;/span&gt;
&lt;span class='c1'&gt;# transform it in HTML&lt;/span&gt;
&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$html&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;markdown&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$text&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='c1'&gt;# Then we loop on all the other blog to cross post to&lt;/span&gt;
&lt;span class='k'&gt;foreach&lt;/span&gt; &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$site&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;grep&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nv'&gt;$_&lt;/span&gt; &lt;span class='ow'&gt;ne&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;main_blog&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='nb'&gt;keys&lt;/span&gt; &lt;span class='nv'&gt;%$cfg&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;say&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;posting to $site&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;%properties&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;%&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nv'&gt;$cfg&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nv'&gt;$site&lt;/span&gt;&lt;span class='p'&gt;}};&lt;/span&gt;

    &lt;span class='c1'&gt;# for now we handle only movable type&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$properties&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;type&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='ow'&gt;eq&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;mt&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$username&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$properties&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;username&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;
        &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$password&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$properties&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;password&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;
        &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$url&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$properties&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;url&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;

        &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$mt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nn'&gt;Net::&lt;/span&gt;&lt;span class='n'&gt;MovableType&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$url&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;username&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$username&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;errstr&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;password&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$password&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;errstr&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='n'&gt;We&lt;/span&gt; &lt;span class='n'&gt;need&lt;/span&gt; &lt;span class='n'&gt;to&lt;/span&gt; &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='n'&gt;the&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='err'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt; &lt;span class='n'&gt;blog&lt;/span&gt; &lt;span class='n'&gt;id&lt;/span&gt;
        &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$user_blogs&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;getUsersBlogs&lt;/span&gt;
          &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;errstr&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;blogId&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$user_blogs&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;blogid&lt;/span&gt;&lt;span class='p'&gt;})&lt;/span&gt;
          &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='n'&gt;croak&lt;/span&gt; &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;errstr&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

        &lt;span class='c1'&gt;# finally, the post&lt;/span&gt;
        &lt;span class='nv'&gt;$mt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;newPost&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
                      &lt;span class='n'&gt;title&lt;/span&gt;       &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;$title&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                      &lt;span class='n'&gt;description&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;$html&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                      &lt;span class='n'&gt;mt_allow_comments&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;$properties&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;allow_comments&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='sr'&gt;//&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                     &lt;span class='p'&gt;},&lt;/span&gt;
                     &lt;span class='c1'&gt;# uncomment this line to directly post it&lt;/span&gt;
                     &lt;span class='c1'&gt;# 1&lt;/span&gt;
                    &lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='p'&gt;}&lt;/span&gt;
    
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Missing in this code is some mungling of the text to manage jekyll specific syntax. And while I was at it, I improved it so that it supports cross-posting to twitter, using &lt;a href='https://metacpan.org/module/Net::Twitter'&gt;Net::Twitter&lt;/a&gt;, and posting only a short description of the entry. Here is an example (I had to create a custom Twitter app called blog-cross-poster)&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/twitter_cross_post.png' alt='Twitter cross posting' /&gt;&lt;/p&gt;

&lt;p&gt;Now, I just need to add a git hook to be executed at push time, check if there is a new post or a modified one, and cross post it. Yay !&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/ROBK8LFSeko" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/04/05/cross-posting-to-blogsperlorg.html</feedburner:origLink></entry>
 
 <entry>
   <title>Perl, fun again!</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/sTts0XVCou8/perlfunagain.html" />
   <updated>2012-03-02T00:00:00-08:00</updated>
   <id>http://dams.github.com/2012/03/02/perlfunagain</id>
   <content type="html">&lt;h1 id='perl_fun_again'&gt;Perl, fun again!&lt;/h1&gt;

&lt;p&gt;I&amp;#8217;m happy to announce a new Perl event that will be held in Paris (France) next Monday, presented by the &lt;a href='http://mongueurs.typepad.com/'&gt;French&lt;/a&gt; &lt;a href='http://mongueurs.net/'&gt;Perl&lt;/a&gt; &lt;a href='http://planet.mongueurs.net/'&gt;Mongers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s called &lt;strong&gt;Perl, fun again!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It will be held at &lt;a href='http://lacantine.org/events/perl-fun-again'&gt;La cantine&lt;/a&gt; Monday 5 March 2012, in the evening.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://www.sukria.net/fr/wp-content/uploads/2012/02/6234213565_830637e185_m.jpg' alt='La Cantine' /&gt;&lt;/p&gt;

&lt;p&gt;From 19:00 to 22:00, a set of short talks (15 min) will be given. I expect a wide audience, beyond Perl users, primarily geeks, coders, web designers, administrators, basically IT-related people with some knowledge of programming ( in any language), and interested in seeing what makes Perl so appealing these days.&lt;/p&gt;

&lt;p&gt;I organised the event ( representing the French Perl Mongers ), with the help of Laurent Boivin, and &lt;em&gt;La cantine&lt;/em&gt;, kindly hosting the event for free. I managed to enroll 8 speakers, including some well-known Perl figures, to deliver the following set of talks. &lt;em&gt;Of course, in French :)&lt;/em&gt; :&lt;/p&gt;

&lt;p&gt;19:00&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perl Intro ( Sylvain Lhullier )&lt;/li&gt;

&lt;li&gt;Modern Perl Object with Moose (Damien &amp;#8220;dams&amp;#8221;Krotkine )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;20:00&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dancer, the light web framework ( Alexis &amp;#8220;sukria&amp;#8221; Sukrieh )&lt;/li&gt;

&lt;li&gt;Perl and NoSQL, with MongoDB. ( Jean-Marie Gouarné )&lt;/li&gt;

&lt;li&gt;Build a webservice easily with Dancer &amp;amp; Spore ( Camille Maussang )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;21:00&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to deploy modules and applications with Perl ( Vincent Pit )&lt;/li&gt;

&lt;li&gt;Debug and profile with Perl and NYTProf ( David Morel )&lt;/li&gt;

&lt;li&gt;Perl development, Perl future ( Rafael &amp;#8220;rgs&amp;#8221; Garcia-Suarez )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I&amp;#8217;d like to thank the speakers to devote their time and passion to help promoting Perl in France.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/sTts0XVCou8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/03/02/perlfunagain.html</feedburner:origLink></entry>
 
 <entry>
   <title>Dancer::Plugin::Params::Normalization</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/82RZ1uZrEHQ/dancerpluginparamsnormalization.html" />
   <updated>2012-02-27T00:00:00-08:00</updated>
   <id>http://dams.github.com/2012/02/27/dancerpluginparamsnormalization</id>
   <content type="html">&lt;h1 id='dancerpluginparamsnormalization'&gt;Dancer::Plugin::Params::Normalization&lt;/h1&gt;

&lt;p&gt;Just released a new version of &lt;a href='https://metacpan.org/module/Dancer::Plugin::Params::Normalization'&gt;Dancer::Plugin::Params::Normalization&lt;/a&gt;. This plugin allows to normalize or alter parameters recieved by a Dancer route.&lt;/p&gt;

&lt;p&gt;An example of what developers usually want is to accept mixedcased request parameters, and have them all lowercased. That is done easily :&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# In your configuration file
plugins:
  Params::Normalization:
    method: lowercase&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that&amp;#8217;s it, now you are sure that all your parameter names will be lowercases.&lt;/p&gt;

&lt;p&gt;Now this plugin goes further by being very flexible and powerful. It supports standard methods like &lt;em&gt;lowercase&lt;/em&gt;, &lt;em&gt;uppoercase&lt;/em&gt;, &lt;em&gt;ucfirst&lt;/em&gt;. But you can also give it a class name, which have to implement a &lt;em&gt;normalize&lt;/em&gt; method, thus giving you full flexibility.&lt;/p&gt;

&lt;p&gt;If you don&amp;#8217;t want all parameters of all routes to be normalized, you can set &lt;em&gt;general_rule&lt;/em&gt; to &lt;em&gt;ondemand&lt;/em&gt;, and use the added keyword &lt;em&gt;normalize&lt;/em&gt; to trigger the normalization. Or, you can instead specify a filter to be applied on parameters. Only those matching it will be normalized.&lt;/p&gt;

&lt;p&gt;But that&amp;#8217;s not the end. This plugin also allows you to specify which parameters should be normalized: &lt;em&gt;query&lt;/em&gt; parameters, &lt;em&gt;body&lt;/em&gt; parameters, or the parameters from the &lt;em&gt;route&lt;/em&gt; definitions.&lt;/p&gt;

&lt;p&gt;I tried to be pretty exhaustive with this plugin, but if anything happen to be missing for your usage, let me know :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/82RZ1uZrEHQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/02/27/dancerpluginparamsnormalization.html</feedburner:origLink></entry>
 
 <entry>
   <title>Paris.pm January Technical Meeting</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/xGPHqfrkH5w/parispm-january-technical-meeting.html" />
   <updated>2012-01-13T00:00:00-08:00</updated>
   <id>http://dams.github.com/2012/01/13/parispm-january-technical-meeting</id>
   <content type="html">&lt;h1 id='parispm_january_technical_meeting'&gt;Paris.pm January Technical Meeting&lt;/h1&gt;

&lt;p&gt;( french version below )&lt;/p&gt;

&lt;p&gt;Since September 2011, I&amp;#8217;ve taken over the management of the &lt;a href='http://goo.gl/1i6rI'&gt;Paris.pm&lt;/a&gt; monthly technical meetings. Paris.pm is part of the &lt;a href='http://goo.gl/DVhUw'&gt;French Perl Mongers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These meetings happen every months in a very nice building in Paris (it&amp;#8217;s an ancient rail station), and usually 15 people gather for one evening. We are relatively well equipped, with a video beamer, microphone and video camera. Thanks to other mongers that help, things go smotthly.&lt;/p&gt;

&lt;p&gt;The next meeting will happen the &lt;strong&gt;18th january 2012&lt;/strong&gt;, with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guillaume Rousse: advanced LWP&lt;/li&gt;

&lt;li&gt;Pierre Marc: demonstration of the &lt;a href='http://goo.gl/AKTFq'&gt;Nirva Systems&lt;/a&gt; Application Server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt; : 181 avenue Daumesnil, 75012 Paris, France&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goggle map&lt;/strong&gt; : &lt;a href='http://goo.gl/OGUbI'&gt;google map&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are interested, and live in Paris, please join us ! it&amp;#8217;s free of course.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Depuis septembre 2011, j&amp;#8217;ai repris la gestion des réunions techniques de &lt;a href='http://goo.gl/1i6rI'&gt;Paris.pm&lt;/a&gt; (groupe parisien des &lt;a href='http://goo.gl/DVhUw'&gt;Mongueurs de Perl&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Ces réunions ont lieu tous les mois dans des très beaux locaux dans Paris (l&amp;#8217;ancienne gare de Bercy), et accueille habituellement une quinzaine de personnes, intéressées par Perl . Nous sommes relativement bien équipé, avec projecteur, micro et caméra, et grâce à l&amp;#8217;aide des autres mongueurs, tout se passe bien.&lt;/p&gt;

&lt;p&gt;Lors de ces réunions, deux à trois présentations techniques ont lieu, suivis de questions. Le tout se fini généralement dans un restaurant dans le coin.&lt;/p&gt;

&lt;p&gt;La prochaine réunion se tient mercredi &lt;strong&gt;18 janvier 2012&lt;/strong&gt;, et le programme est :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guillaume Rousse : LWP avancé&lt;/li&gt;

&lt;li&gt;Pierre Marc : présentation du serveur d&amp;#8217;application de &lt;a href='http://goo.gl/AKTFq'&gt;Nirva Systems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adresse&lt;/strong&gt; : 181 avenue Daumesnil, 75012 Paris&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lien goggle map&lt;/strong&gt; : &lt;a href='http://goo.gl/OGUbI'&gt;google map&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si vous êtes intéressé, n&amp;#8217;hésitez pas à venir, entrée libre et gratuite.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/xGPHqfrkH5w" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2012/01/13/parispm-january-technical-meeting.html</feedburner:origLink></entry>
 
 <entry>
   <title>protect a screen session with a password</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/0RdG1Fqq_Vw/protect-a-screen-session-with-a-password.html" />
   <updated>2011-09-01T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/09/01/protect-a-screen-session-with-a-password</id>
   <content type="html">&lt;h1 id='protect_a_screen_session_with_a_password'&gt;protect a screen session with a password&lt;/h1&gt;

&lt;p&gt;At work, I&amp;#8217;m currently deploying my Perl modules on a new platform ( multiple servers ), which doesn&amp;#8217;t have an automated deployment mechanism yet. I use &lt;a href='http://www.gnu.org/software/screen/'&gt;Gnu Screen&lt;/a&gt; a lot. It&amp;#8217;s a must have tool when working on remote servers.&lt;/p&gt;

&lt;p&gt;Long time ago, I spent time to craft a good &lt;code&gt;.screenrc&lt;/code&gt; configuration file for my needs. But I only discovered yesterday that I could protect my screen session from being recovered from a super user on the remote server. The documentation is lacking precise description on how to set it up, so here is a quick tutorial.&lt;/p&gt;

&lt;p&gt;The idea is that when a screen is running, it can be detached and reattached. However, a super user has the possibility to attach any screen launched by a user of the system. Now, what if inside the screen, you use sensitive informations, or connect to other remote servers ? The super user will have access to these as well. To protect yourself from that (actually to mitigate the issue), it&amp;#8217;s possible to have screen ask for a password when trying to reattach it.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;DISCLAIMER&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In no way this method will prevent &lt;code&gt;root&lt;/code&gt; to access your sensitive information. This method will just make it more difficult for a super user to see your screen content using &lt;code&gt;su $user&lt;/code&gt; and &lt;code&gt;screen -r -d&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As &lt;code&gt;daxim&lt;/code&gt; pointed out on &lt;em&gt;#dancer&lt;/em&gt;, there are numerous ways for &lt;code&gt;root&lt;/code&gt; to get at your sensitive information :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;attach to the process with a debugger, then skip the password check when it comes up&lt;/li&gt;

&lt;li&gt;read the process memory of screen and dig out interesting stuff&lt;/li&gt;

&lt;li&gt;install a network monitor and grabs your password as it is transmitted next time. rsa encryption (via ssh) does not help because root also has the keys&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id='launch_a_new_screen'&gt;Launch a new screen&lt;/h2&gt;

&lt;p&gt;Easily done :&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;screen
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='encrypt_a_new_password'&gt;Encrypt a new password&lt;/h2&gt;

&lt;p&gt;screen provides a way to encrypt a password right from a screen session. In the following snippets, I assume the default screen key is A, as default.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;# hit ctrl A :password&lt;/span&gt;
&lt;span class='c'&gt;# enter the new password twice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, the encrypted password is in the screen clipboard. We need to retrieve it&lt;/p&gt;

&lt;h2 id='paste_the_crypted_password'&gt;Paste the crypted password&lt;/h2&gt;

&lt;p&gt;The key shortcut for pasting the clipboard is by default &lt;code&gt;Ctrl-A ]&lt;/code&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;# hit ctrl A ]&lt;/span&gt;
&lt;span class='c'&gt;# the encrypted password should be pasted in the console&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='edit_the_screen_configuration_file'&gt;Edit the screen configuration file&lt;/h2&gt;

&lt;p&gt;Copy the encrypted password and paste it in &lt;code&gt;~/.screenrc&lt;/code&gt; (or whatever your screen configuration file is)&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;# add this line, with your encrypted password&lt;/span&gt;
password VGdGzMopF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='restart_screen'&gt;Restart screen&lt;/h2&gt;

&lt;p&gt;You need to restart screen to take the password in account. Now, next time a screen is reattached, the password will be prompted.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;dams@foo:~&lt;span class='nv'&gt;$ &lt;/span&gt;screen -r -d plop
Screen password: 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/0RdG1Fqq_Vw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/09/01/protect-a-screen-session-with-a-password.html</feedburner:origLink></entry>
 
 <entry>
   <title>Moose and enum</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/Z67S8zaBqwU/enum-in-moose.html" />
   <updated>2011-06-17T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/06/17/enum-in-moose</id>
   <content type="html">&lt;h1 id='moose_and_enum'&gt;Moose and enum&lt;/h1&gt;

&lt;p&gt;At $work, we are using Moose a lot. So I spend a lot of time declaring attributes, and some of them are Strings that should be picked from a fixed list of values.&lt;/p&gt;

&lt;p&gt;For instance, I need to be able to define a &lt;code&gt;task&lt;/code&gt; that can be only one of &lt;code&gt;&amp;#39;profit&amp;#39;&lt;/code&gt;, &lt;code&gt;&amp;#39;world_domination&amp;#39;&lt;/code&gt;. And use it like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='c1'&gt;# works fine&lt;/span&gt;
&lt;span class='nv'&gt;$attribute&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;task&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;profit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='c1'&gt;# fails&lt;/span&gt;
&lt;span class='nv'&gt;$attribute&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;task&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;failure&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So basically, the attribute is an &lt;code&gt;enum&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='the_painful_way'&gt;The painful way&lt;/h2&gt;

&lt;p&gt;Until now, I was defining a new subtype for each &lt;code&gt;enum&lt;/code&gt; I needed. Something like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='c1'&gt;# type definition&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Moose::Util::&lt;/span&gt;&lt;span class='n'&gt;TypeConstraints&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='n'&gt;subtype&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;My:Type:Task&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;as&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Str&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class='n'&gt;where&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$r&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;|&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;__PACKAGE__&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;get_possible_tasks&lt;/span&gt; &lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='sr'&gt;/^(?:$r)$/&lt;/span&gt; &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='n'&gt;coerce&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;My:Type:Task&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;from&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;Str&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;via&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nb'&gt;lc&lt;/span&gt;&lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;get_possible_tasks&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='sx'&gt;qw(profit world_domination)&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='c1'&gt;# attribute declaration&lt;/span&gt;
&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='n'&gt;task&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='n'&gt;isa&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;My:Type:Task&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s very verbose, painful and not readable, isn&amp;#8217;t it ?&lt;/p&gt;

&lt;h2 id='the_right_way'&gt;The right way&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Moose::Util::TypeConstraints&lt;/code&gt; provides the &lt;code&gt;enum&lt;/code&gt; method, that serves exactly our purpose. It&amp;#8217;s basically a shortcut to create a subtype based on &amp;#8216;Str&amp;#8217;, limited to a list of possible values. You can use it to build a &lt;em&gt;named&lt;/em&gt; enum subtype, or an &lt;em&gt;anonymous&lt;/em&gt; subtype. See the usage in our case :&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='c1'&gt;# using a named enum subtype:&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Moose::Util::&lt;/span&gt;&lt;span class='n'&gt;TypeConstraints&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='n'&gt;enum&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;My:Enum:Task&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='sx'&gt;qw(profit world_domination)&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='n'&gt;task&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='n'&gt;isa&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;My:Enum:Task&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='c1'&gt;# using an anonymous enum subtype:&lt;/span&gt;
&lt;span class='k'&gt;use&lt;/span&gt; &lt;span class='nn'&gt;Moose::Util::&lt;/span&gt;&lt;span class='n'&gt;TypeConstraints&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='n'&gt;task&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='n'&gt;isa&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;enum&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='sx'&gt;qw(profit world_domination)&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt; &lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So that&amp;#8217;s all, I guess this kind of feature is nothing new for seasoned Moose developers, but it may help beginners, as there is no mention of &lt;code&gt;enum&lt;/code&gt; in &lt;code&gt;Moose::Manual::Attributes&lt;/code&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/Z67S8zaBqwU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/06/17/enum-in-moose.html</feedburner:origLink></entry>
 
 <entry>
   <title>Perlbrew, Emacs, Flymake</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/9seIJcqr-ek/perlbrew-emacs-flymake.html" />
   <updated>2011-05-27T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/05/27/perlbrew-emacs-flymake</id>
   <content type="html">&lt;h1 id='perlbrew_emacs_flymake'&gt;Perlbrew, Emacs, Flymake&lt;/h1&gt;

&lt;p&gt;So I&amp;#8217;m a seasoned user of &lt;a href='http://www.gnu.org/software/emacs/'&gt;Emacs&lt;/a&gt; (I started using it back to 1999). I&amp;#8217;m using it for all things, especially Perl coding, using the &lt;code&gt;cperl-mode&lt;/code&gt; Emacs mode.&lt;/p&gt;

&lt;p&gt;Lately, I&amp;#8217;ve come to using &lt;code&gt;flymake&lt;/code&gt;. &lt;a href='http://flymake.sourceforge.net/'&gt;Flymake&lt;/a&gt; is a tool in Emacs, which tries to compile the file you are editing, and displays compilation errors in your buffer. There is a mode for Perl, so the result is really nice : realtime syntax checking of the current Perl file you&amp;#8217;re editing. It looks like that :&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/perl_flymake.png' alt='Perl and Flymake in Emacs' /&gt;&lt;/p&gt;

&lt;h1 id='perl__emacs__flymake__perlbrew'&gt;Perl + Emacs + Flymake + PerlBrew&lt;/h1&gt;

&lt;p&gt;Then comes &lt;a href='http://search.cpan.org/perldoc?App::perlbrew'&gt;perlbrew&lt;/a&gt;, which allows you to have multiple Perl interpretors installed on your machine, and switching between them easily.&lt;/p&gt;

&lt;p&gt;Alas, flymake is not working by default with Perlbrew, as it uses &lt;code&gt;/usr/bin/perl&lt;/code&gt;. So one needs to configure Emacs to recognize various perls installed via Perlbrew, and tell Flymake to use one of them.&lt;/p&gt;

&lt;p&gt;kentaro has made a Perlbrew mode, and &lt;a href='http://d.hatena.ne.jp/antipop/20110413/1302671667'&gt;explained how to use it with flymake&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, for various reasons, this Perlbrew mode it doesn&amp;#8217;t work well on my machine and Franck ( &lt;a href='http://lumberjaph.net/'&gt;lumperjaph&lt;/a&gt; ) reported similar issues.&lt;/p&gt;

&lt;p&gt;So I went on and rewrote a simple Perlbrew mode that would do almost nothing. It would only play with directories path, to allow you to say where the various Perlbrew perls are installed, and which one to use. &lt;code&gt;perlbrew-mini.el&lt;/code&gt; was born.&lt;/p&gt;

&lt;h1 id='perlbrewminiel'&gt;perlbrew-mini.el&lt;/h1&gt;

&lt;p&gt;Requirements : you need Emacs, a functional perlbrew with at least one Perl installed, and you need &lt;a href='http://search.cpan.org/perldoc?Project::Libs'&gt;Project::Libs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, download perlbrew-mini.el &lt;a href='https://github.com/dams/perlbrew-mini.el'&gt;from github&lt;/a&gt;, and put it in a place where Emacs will see it.&lt;/p&gt;

&lt;p&gt;Then, edit your &lt;code&gt;.emacs&lt;/code&gt; so that it contains these lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(require &amp;#39;perlbrew-mini)
;; change to your username below
(perlbrew-mini-set-perls-dir &amp;quot;/home/uername/perl5/perlbrew/perls/&amp;quot;)
;; change the version you wish to use
(perlbrew-mini-use &amp;quot;perl-5.12.2&amp;quot;)

(require &amp;#39;flymake)

(defun flymake-perl-init ()
  (let* ((temp-file (flymake-init-create-temp-buffer-copy
                     &amp;#39;flymake-create-temp-inplace))
         (local-file (file-relative-name
                      temp-file
                      (file-name-directory buffer-file-name))))
    (list (perlbrew-mini-get-current-perl-path)
          (list &amp;quot;-MProject::Libs&amp;quot; &amp;quot;-wc&amp;quot; local-file)))
)

(add-hook &amp;#39;cperl-mode-hook (lambda () (flymake-mode t)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And &lt;em&gt;voilà&lt;/em&gt;, Flymake will work with your Perlbrew Perl, as it used to work with the system Perl.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/9seIJcqr-ek" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/05/27/perlbrew-emacs-flymake.html</feedburner:origLink></entry>
 
 <entry>
   <title>DateTime duration in seconds</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/Ul6MyI5B1yE/datetime-duration-in-seconds.html" />
   <updated>2011-05-25T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/05/25/datetime-duration-in-seconds</id>
   <content type="html">&lt;h1 id='datetime_duration_in_seconds'&gt;DateTime duration in seconds&lt;/h1&gt;

&lt;p&gt;It has been too many times that I forget how to get a &lt;code&gt;DateTime::Duration&lt;/code&gt; between two &lt;code&gt;DateTime&lt;/code&gt; objects in seconds (and nanoseconds). That is, where I can then do &lt;code&gt;-&amp;gt;seconds&lt;/code&gt; and have the duration in seconds between the two dates.&lt;/p&gt;

&lt;p&gt;I know it&amp;#8217;s in the &lt;code&gt;DateTime&lt;/code&gt; POD, but I keep forgetting it, and it takes me always a lot of time to find it back.&lt;/p&gt;

&lt;p&gt;Here it is so that hopefully the next time I search for &amp;#8220;Perl DateTime Duration seconds&amp;#8221; on the Intarweb, it shows up&amp;#8230;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$duration&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$dt2&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;subtract_datetime_absolute&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$dt1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$seconds&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$duration&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;seconds&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/Ul6MyI5B1yE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/05/25/datetime-duration-in-seconds.html</feedburner:origLink></entry>
 
 <entry>
   <title>Simple usage of Perl state variables</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/UA_dd4iLAmk/simple-usage-of-state-variables.html" />
   <updated>2011-05-24T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/05/24/simple-usage-of-state-variables</id>
   <content type="html">&lt;h1 id='simple_usage_of_perl_state_variables'&gt;Simple usage of Perl state variables&lt;/h1&gt;

&lt;p&gt;I see this type of code too often:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='nb'&gt;package&lt;/span&gt; &lt;span class='n'&gt;Foo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$structure&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{};&lt;/span&gt;
  &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;plop&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='c1'&gt;#...&lt;/span&gt;
      &lt;span class='nv'&gt;$structure&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nv'&gt;$foo&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
      &lt;span class='c1'&gt;#...&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or things like that:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='nb'&gt;package&lt;/span&gt; &lt;span class='n'&gt;Foo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;my&lt;/span&gt; &lt;span class='nv'&gt;$cache&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;plop&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='c1'&gt;#...&lt;/span&gt;
      &lt;span class='nb'&gt;defined&lt;/span&gt; &lt;span class='nv'&gt;$cache&lt;/span&gt; &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='nv'&gt;$cache&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;_load_cache&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='c1'&gt;#...&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are using a non-ancient version of Perl (that is, 5.10 or more), you should consider using the &lt;code&gt;state&lt;/code&gt; keyword. It&amp;#8217;s similar to the static variables inherited from C.&lt;/p&gt;

&lt;p&gt;From the &lt;a href='http://perldoc.perl.org/functions/state.html'&gt;documentation&lt;/a&gt; :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;state&lt;/code&gt; declares a lexically scoped variable, just like &lt;code&gt;my&lt;/code&gt; does. However, those variables will never be reinitialized, contrary to lexical variables that are reinitialized each time their enclosing block is entered.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the two code snippets become :&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='nb'&gt;package&lt;/span&gt; &lt;span class='n'&gt;Foo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;plop&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;state&lt;/span&gt; &lt;span class='nv'&gt;$structure&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{};&lt;/span&gt;
    &lt;span class='nv'&gt;$structure&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nv'&gt;$foo&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='c1'&gt;#...&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;&lt;span class='nb'&gt;package&lt;/span&gt; &lt;span class='n'&gt;Foo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='k'&gt;sub &lt;/span&gt;&lt;span class='nf'&gt;plop&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;#...&lt;/span&gt;
    &lt;span class='n'&gt;state&lt;/span&gt; &lt;span class='nv'&gt;$cache&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;_load_cache&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='c1'&gt;#...&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nothing terribly amazing here, but it&amp;#8217;s really easy, saves keystrokes and makes the code more readable. So why not use it more widely ?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/UA_dd4iLAmk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/05/24/simple-usage-of-state-variables.html</feedburner:origLink></entry>
 
 <entry>
   <title>Moose trick with MooseX-Getopt and roles</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/-LMQhy7ykvg/MooseX-Getopt-trick.html" />
   <updated>2011-05-18T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/05/18/MooseX-Getopt-trick</id>
   <content type="html">&lt;h1 id='moose_trick_with_moosexgetopt_and_roles'&gt;Moose trick with MooseX-Getopt and roles&lt;/h1&gt;
&lt;p class='meta'&gt; 18 May 2011 - Paris&lt;/p&gt;
&lt;h1 id='on_moosexgetopt'&gt;On MooseX::Getopt&lt;/h1&gt;

&lt;p&gt;At work I extensively use Moose in my everyday Perl coding. I also use &lt;a href='http://search.cpan.org/perldoc?MooseX::Getopt'&gt;MooseX::Getopt&lt;/a&gt; to automatically handle command line arguments as attributes, thus simplifying the implementation of scripts.&lt;/p&gt;

&lt;p&gt;By default, MooseX::Getopt consider all public attributes to be mapped on a command line argument. There are many ways to tell MooseX::Getopt to ignore a public attribute:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you can turn your attribut to a private one, but with public accessors&lt;/li&gt;

&lt;li&gt;you can have the attribute use &lt;a href='http://search.cpan.org/perldoc?MooseX::Getopt::Meta::Attribute::Trait::NoGetopt'&gt;MooseX::Getopt::Meta::Attribute::Trait::NoGetopt&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;you can have the attribute use the &lt;a href='http://search.cpan.org/perldoc?MooseX::Getopt::Meta::Attribute::NoGetopt'&gt;MooseX::Getopt::Meta::Attribute::NoGetopt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id='act_on_distant_attributes'&gt;Act on distant attributes&lt;/h1&gt;

&lt;p&gt;The previous actions are to be performed on the attribute definition. But what about the situations where you don&amp;#8217;t write the attribute definition yourself ? Like, for instance, if you inherits the attributes from an other class, or if you got the attributes by consuming a role ?&lt;/p&gt;

&lt;p&gt;In this case, you&amp;#8217;ll need to perform an action on the attribute &lt;strong&gt;from a distance&lt;/strong&gt;. Here are two solutions, that were given to me by the nice folks on #moose (namely &lt;em&gt;sartak&lt;/em&gt; and &lt;em&gt;doy&lt;/em&gt;)&lt;/p&gt;

&lt;h2 id='apply_the_trait_from_a_distance'&gt;Apply the trait from a distance&lt;/h2&gt;

&lt;p&gt;The first solution is to run this code after having consumed a role, or inherited a class, that provides the attribute &amp;#8216;some_attr&amp;#8217;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;   &lt;span class='nn'&gt;MooseX::Getopt::Meta::Attribute::Trait::&lt;/span&gt;&lt;span class='n'&gt;NoGetopt&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;apply&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
       &lt;span class='n'&gt;__PACKAGE__&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;meta&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='n'&gt;get_attribute&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;some_attr&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
   &lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='adds_the_trait_to_the_attribute_definition'&gt;Adds the trait to the attribute definition&lt;/h2&gt;

&lt;p&gt;A syntactically simpler solution is to add the trait in the attribute, in our class:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='perl'&gt;    &lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;+some_attr&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;traits&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;NoGetopt&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &amp;#8217;+&amp;#8217; character allows to add things to an already defined attribute, instead of trying to overwrite its definition altogether.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/-LMQhy7ykvg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/05/18/MooseX-Getopt-trick.html</feedburner:origLink></entry>
 
 <entry>
   <title>Migrating to Jekyll</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/UVI2hZo__a4/migrating-to-jekyll.html" />
   <updated>2011-04-30T00:00:00-07:00</updated>
   <id>http://dams.github.com/2011/04/30/migrating-to-jekyll</id>
   <content type="html">&lt;h1 id='migrating_to_jekyll'&gt;Migrating to Jekyll&lt;/h1&gt;
&lt;p class='meta'&gt; 30 Apr 2011 - Paris&lt;/p&gt;
&lt;p&gt;So, this post is about migrating this blog from &lt;a href='http://typepad.com'&gt;Typepad&lt;/a&gt; to &lt;a href='http://jekyllrb.com/'&gt;Jekyll&lt;/a&gt;, using a small Perl script.&lt;/p&gt;

&lt;p&gt;The reasons why I&amp;#8217;m moving away from Typepad are :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typepad is slow&lt;/li&gt;

&lt;li&gt;Typepad is not free&lt;/li&gt;

&lt;li&gt;Typepad editor is not techie compatible&lt;/li&gt;

&lt;li&gt;Typepad is a blog engine&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And blog engines are not hype anymore :) Seriously, I was looking for something easy and simple, and compatible with my geek side.&lt;/p&gt;

&lt;p&gt;Back in the days, I remember that I enjoyed a lot using &lt;a href='http://nanoblogger.sourceforge.net/'&gt;nanoblogger&lt;/a&gt;. But it&amp;#8217;s too slow, and you need to host it yourself.&lt;/p&gt;

&lt;p&gt;So I followed the current trend, and set up my pages on github, and transfered my posts from Typepad to jekyll.&lt;/p&gt;

&lt;p&gt;Jekyll is :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;light&lt;/li&gt;

&lt;li&gt;easy&lt;/li&gt;

&lt;li&gt;simple&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the real power is that it can be coupled with github&amp;#8217;s pages. So I feel right at home, and so editing code and pushing to git(hub) (stuff I do everyday) won&amp;#8217;t be different from editing blog posts and pushing to github.&lt;/p&gt;

&lt;p&gt;Oh, but how did I migrate my blog posts from Typepad to Jekyll ? I couldn&amp;#8217;t find any migration script on internet or importers in jekyll, so I wrote a quick and not so dirty Perl script. it&amp;#8217;s all on github here : the mighty &lt;a href='https://github.com/dams/typepad_to_jekyll'&gt;typepad_to_jekyll&lt;/a&gt; ! Feel free to fork it. Feedback welcome :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/UVI2hZo__a4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2011/04/30/migrating-to-jekyll.html</feedburner:origLink></entry>
 
 <entry>
   <title>Perl Moderne, a new Perl book</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/m3hWt7wEPJ8/perl-moderne-a-new-perl-book.html" />
   <updated>2011-02-16T00:00:00-08:00</updated>
   <id>http://dams.github.com/All/Perl/2011/02/16/perl-moderne-a-new-perl-book</id>
   <content type="html">&lt;p&gt;&lt;a href="http://perlmoderne.fr" style="float: left;"&gt;&lt;img alt="image from www.pearson.fr" class="asset  asset-image at-xid-6a0120a63366ed970b014e861c3dc0970d" src="http://damien.krotkine.com/.a/6a0120a63366ed970b014e861c3dc0970d-800wi" style="border: 1px solid black; margin: 10px 10px 10px 10px;" title="Perl Moderne" /&gt;&lt;/a&gt; I haven&amp;#39;t been blogging a lot this year-and-half, and for various reasons. But the reason number one is that I&amp;#39;ve been very busy writing a &lt;strong&gt;&lt;a href="http://perlmoderne.fr/" target="_self"&gt;Perl book&lt;/a&gt;&lt;/strong&gt; from scratch, in French, with 3 other fellow French &lt;a href="http://mongueurs.net/" target="_self"&gt;Perl Mongers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The book is called &lt;em&gt;&lt;a href="http://perlmoderne.fr/" target="_self"&gt;Perl Moderne&lt;/a&gt;&lt;/em&gt;. That means &amp;quot;Modern Perl&amp;quot;, but it has nothing to do with chromatic&amp;#39;s book. The book was actually published long time ago, end October 2010. But it took us authors some time to recover :)&lt;/p&gt;
&lt;p&gt;This book is written in French, for French speaking readers. Its goal is to present the Perl 5 language as it exists &lt;strong&gt;now&lt;/strong&gt;, and tries to teach the reader how to start using it the &lt;em&gt;right way&lt;/em&gt;, that is, the &lt;em&gt;modern way&lt;/em&gt;. The book is not a bible, nor an encyclopedia of the historical language. Instead, it&amp;#39;s a collection of the useful concepts that are used nowadays, and how to use them in the latest version of Perl and CPAN.&lt;/p&gt;
&lt;p&gt;The reader can be a total newbie in Perl, but it has to have a previous development experience with an other language, for instance PHP, Ruby, Python, or Java. However, the book goes far beyond introducing the language. It allows the reader to become fluent with the Perl data structure, regexps, Moose OO and typing, POE, interacting with databases, files, DateTime, XML and configuration files, Web interactions, and more...&lt;/p&gt;
&lt;p&gt;It&amp;#39;s big in content (many subjects covered, and 450 pages !) but small in size, as it&amp;#39;s an A5 format, so it fits easily in a bag, and it&amp;#39;s not heavy :)&lt;/p&gt;
&lt;h2&gt;The people&lt;/h2&gt;
&lt;p&gt;Historically, Pearson France, the press editor, posted a request on the French Perl Mongers mailing list, saying that they were looking for authors willing to write a new Perl Book in French.&lt;/p&gt;
&lt;p&gt;I decided to not let this opportunity pass : it&amp;#39;s very rare that French editors are interested by Perl, and willing to produce good quality books. After some struggling, I ended up setting up a team of 4 brave French Perl Mongers, that became 4 Perl book authors :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sébastien Aperghis-Tramoni&lt;/strong&gt;&amp;#0160;(SAPER on CPAN) : active French Perl Monger, he knows almost everything about CPAN modules. He wrote several modules himself, and maintains numerous others. He wrote several Perl articles in the &lt;a href="http://www.gnulinuxmag.com" target="_self"&gt;GNU/Linux Magazine France&lt;/a&gt;.&amp;#0160;He is also the hidden admin of your Perl conferences, as he maintains &lt;a href="http://act.mongueurs.net/" target="_self"&gt;Act&lt;/a&gt;, empowering a lot of &lt;a href="http://act.mongueurs.net/conferences.html" target="_self"&gt;Perl conferences&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Philippe Bruhat&lt;/strong&gt;&amp;#0160;(BOOK on CPAN) :&amp;#0160;well known Perl figure, active French Perl Monger, former president of them, founder and treasurer of the&amp;#0160;&lt;a href="http://www.yapceurope.org" target="_self"&gt;YAPC Europe Foundation&lt;/a&gt;. Received a&amp;#0160;White Camel Award in 2009, and maintains quite a few modules on CPAN. Also wrote articles in the GNU/Linux Magazine France.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Jérôme Quelin&lt;/strong&gt; (JQUELIN&amp;#0160;on CPAN) :&amp;#0160;active French Perl Monger, knows a great deal about Tk, wrote &lt;a href="http://search.cpan.org/perldoc?Games::Risk" target="_self"&gt;Games::Risk&lt;/a&gt;&amp;#0160;among other things, and maintains a bunch of CPAN modules. He is also maintaining a lot of Perl packages at Mandriva and &lt;a href="http://mageia.org" target="_self"&gt;Mageia&lt;/a&gt;.&amp;#0160;Also wrote articles in the GNU/Linux Magazine France.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Damien Krotkine&lt;/strong&gt;&amp;#0160;(DAMS on CPAN) : well that&amp;#39;s me ! I&amp;#39;m an&amp;#0160;active French Perl Monger, using Perl for 11 years or so, I wrote a couple of Perl articles in the GNU/Linux Magazine France, have some modules on CPAN (among them &lt;a href="http://search.cpan.org/perldoc?Curses::Toolkit" target="_self"&gt;Curses::Toolkit&lt;/a&gt;), and I&amp;#39;m now a proud core developer of &lt;a href="http://perldancer.org" target="_self"&gt;Dancer, the new big thing&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The content&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://perlmoderne.fr" target="_self"&gt;&lt;em&gt;Perl Moderne&lt;/em&gt;&lt;/a&gt; starts with a gentle (but concise) introduction to Perl, with many pointers to external resources, focusing on ease-of-use. For instance, we mention CPAN and&amp;#0160;&lt;span style="font-family: &amp;#39;courier new&amp;#39;, courier;"&gt;cpanm&lt;/span&gt;&lt;span&gt;&amp;#0160;very early. Then the real business starts with an explanation of the major programming concepts (data structures, OO, databases, formats, event programming and the intarweb).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We tried to provide a preferred way to do each thing, while mentioning alternatives. We didn&amp;#39;t separated the language and CPAN. &lt;em&gt;&amp;quot;Perl is the syntax, CPAN is the language&amp;quot;&lt;/em&gt;... So about half of the book describes how to solve a problem using this or that CPAN module. And I think it&amp;#39;s great. It allowed us to teach Object Oriented programming with &lt;a href="http://www.iinteractive.com/moose/" target="_self"&gt;Moose&lt;/a&gt;, explain event programming with &lt;a href="http://poe.perl.org/" target="_self"&gt;POE&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;I think it is very important that new Perl books get written, and very important that some are written natively in non-english. It fits better its purpose to the localized need (students, teachers, academic structures and way of thinking are different from one country to another). That also makes editors aware of the local Perl activity, and help spreads the words about the language in schools and universities, where native books are preferred to translations.&lt;/p&gt;
&lt;p&gt;So, if you know any French speaking (or learning) geek or computer scientist, around you, please consider recommending them this book. It was crafted with care and love by Perl passionated ! :) You can point them to the &lt;a href="http://perlmoderne.fr" target="_self"&gt;dedicated website of Perl Moderne&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#0160;&lt;/p&gt;
&lt;p&gt;Here is an english translation of the table of content :&lt;/p&gt;
&lt;p&gt;01. Start with&amp;#0160;Perl&lt;br /&gt;02. Install a&amp;#0160;Perl&amp;#0160;module&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;I. Language and data structures&lt;/strong&gt;&lt;br /&gt;03. Language&lt;br /&gt;04. Data structures&lt;br /&gt;05. Regular expressions&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;II. Modern object programming&lt;/strong&gt;&lt;br /&gt;06. Basic&amp;#0160;Perl&amp;#0160;objects&lt;br /&gt;07. Moose&lt;br /&gt;08. Typing system in Moose&lt;br /&gt;09. Methods in Moose&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;III. Data manipulation&lt;/strong&gt;&lt;br /&gt;10. Files and directories&lt;br /&gt;11. SQL databases&lt;br /&gt;12. SQL abstraction, ORM, non-SQL databases&lt;br /&gt;13. Dates and times&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;IV. Formats&lt;/strong&gt;&lt;br /&gt;14. XML&lt;br /&gt;15. Data serialisation&lt;br /&gt;16. Configuration files&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;V. Event programming&lt;/strong&gt;&lt;br /&gt;17. Introduction to POE&lt;br /&gt;18. Practical POE&lt;br /&gt;19. Distributed POE&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;VI. Web&lt;/strong&gt;&lt;br /&gt;20. HTML documents parsing&lt;br /&gt;21. HTTP and the Web&lt;br /&gt;22. LWP&lt;br /&gt;23. Web browsing&lt;br /&gt;24. WWW::Mechanize&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/m3hWt7wEPJ8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/All/Perl/2011/02/16/perl-moderne-a-new-perl-book.html</feedburner:origLink></entry>
 
 <entry>
   <title>Perl Dancer and DBIC</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/0BzbQfYzUrE/perl-dancer-and-dbic.html" />
   <updated>2010-12-13T00:00:00-08:00</updated>
   <id>http://dams.github.com/2010/12/13/perl-dancer-and-dbic</id>
   <content type="html">&lt;p&gt;Are you curious to see how to create a real app from scratch with Perl Dancer, using DBIX::Class ? Well, my Perl Dancer Advent Calendar article has been published saturday :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://advent.perldancer.org/2010/11" target="_self" title="Perl Advent Calendar article"&gt;http://advent.perldancer.org/2010/11&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://damien.krotkine.com/.a/6a0120a63366ed970b0148c6ac8b3a970c-popup" onclick="window.open( this.href, &amp;#39;_blank&amp;#39;, &amp;#39;width=640,height=480,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0&amp;#39; ); return false" style="display: inline;"&gt;&lt;img alt="Dancer_dbic" class="asset  asset-image at-xid-6a0120a63366ed970b0148c6ac8b3a970c" src="http://damien.krotkine.com/.a/6a0120a63366ed970b0148c6ac8b3a970c-320wi" title="Dancer_dbic" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Enjoy !&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/0BzbQfYzUrE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/12/13/perl-dancer-and-dbic.html</feedburner:origLink></entry>
 
 <entry>
   <title>Disqus on Typepad</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/sPd7RnSgNmE/disqus-on-typepad.html" />
   <updated>2010-12-07T00:00:00-08:00</updated>
   <id>http://dams.github.com/2010/12/07/disqus-on-typepad</id>
   <content type="html">&lt;p&gt;&lt;a href="http://disqus.com" target="_self"&gt;Disqus&lt;/a&gt; is great. It's a full featured cross-site comments free management system. I have an account on it, so I wanted to use disqus instead of the typepad comments system.&lt;/p&gt;
&lt;p&gt;"Easy enough" I said to myself : there is a dedicated page to help you install Disqus in Typepad. This includes adding a new "Embed your own HTML" module in your blog content, and copy-pasting a Javacript snippet in it.&lt;/p&gt;
&lt;p&gt;Alas, the Javascript snippet didn't work fine. I suspect that the Typepad code has changed since the Disqus install documentation has been written. &amp;nbsp;Maybe the Javascript code of Typepad tries to block other scripts playing with the comment tags.&lt;/p&gt;
&lt;p&gt;Anyway, here is a solution : I changed the code a bit, and wrapped it in an Javascript&amp;nbsp;&lt;span style="font-family: 'andale mono', times;"&gt;onload&lt;/span&gt;&amp;nbsp;. I'm not saying it's the best solution, but it works for me... Here is the Javascript code snippet to be used instead of the one Disqus provides in the Typepad Install section. Of course, replace &lt;span style="font-family: 'andale mono', times;"&gt;YOUR_DISQUS_LOGIN&lt;/span&gt; with, well, your disqus login...&lt;/p&gt;


&lt;code class="brush: javascript"&gt;
&amp;lt;script type="text/javascript"&amp;gt;

var my_func = function() {
  var div = document.getElementById('all-comments');
  var script = document.createElement('script');
  script.type = 'text/javascript'; script.src = 'http://disqus.com/forums/YOUR_DISQUS_LOGIN/embed.js';
  document.getElementsByTagName('body')[0].appendChild(script);
  div.innerHTML = '' ;
  div.id = 'disqus_thread';
};

var x = window.onload;
window.onload = function() {my_func(); if (x) x(); }

&amp;lt;/script&amp;gt;
&lt;/code&gt;

Let me know if it works for your Typepad blog.


&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/sPd7RnSgNmE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/12/07/disqus-on-typepad.html</feedburner:origLink></entry>
 
 <entry>
   <title>Perl Dancer version 1.2 and Advent Calendar</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/XOp4BV411-8/perl-dancer-version-1-2-and-advent-calendar.html" />
   <updated>2010-12-01T00:00:00-08:00</updated>
   <id>http://dams.github.com/2010/12/01/perl-dancer-version-1-2-and-advent-calendar</id>
   <content type="html">&lt;p&gt;&amp;#0160;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://perldancer.org/" target="_self" title="Perl Dancer"&gt;Perl Dancer&lt;/a&gt; should at least ring a bell to you : it&amp;#39;s a popular Perl micro web framework. Route based, easy to use, simple clean design, with low dependancies, Dancer is gaining in popularity and maturity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Version 1.2&lt;/strong&gt; has been released ( see &lt;a href="http://www.backup-manager.org/pipermail/dancer-users/2010-November/000513.html" target="_self" title="Dancer 1.2000 announcement"&gt;sawyer&amp;#39;s announcement&lt;/a&gt; here ), and is described as the &lt;em&gt;first stable community release.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But that&amp;#39;s not all ! Go check out the awesome &lt;a href="http://advent.perldancer.org/2010" target="_self" title="Perl Dancer Advent Calendar"&gt;Perl Dancer Advent Calendar&lt;/a&gt;. You&amp;#39;ll learn all about Dancer, how to get started with it, what cool plugins are available, what are the nice tricks. Step by step, a new article will be revealed each day.&lt;/p&gt;
&lt;p&gt;Dancer is a young project with a nice community. Check it out :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;http -&amp;#0160;&lt;a href="http://perldancer.org/" target="_self"&gt;http://perldancer.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IRC - &lt;strong&gt;#dancer&lt;/strong&gt; on&amp;#0160;irc.mongueurs.net&lt;/li&gt;
&lt;li&gt;ml -&amp;#0160;&lt;a href="http://www.backup-manager.org/cgi-bin/listinfo/dancer-users" target="_self"&gt;http://www.backup-manager.org/cgi-bin/listinfo/dancer-users&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;#0160;&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/XOp4BV411-8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/12/01/perl-dancer-version-1-2-and-advent-calendar.html</feedburner:origLink></entry>
 
 <entry>
   <title>Ulimit doesn't work on Leopard (memory limitation)</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/S5zevsGTv7E/ulimit-doesn-t-work-on-leopard-memory-limitation-.html" />
   <updated>2010-10-06T00:00:00-07:00</updated>
   <id>http://dams.github.com/2010/10/06/ulimit-doesn-t-work-on-leopard-memory-limitation-</id>
   <content type="html">&lt;p&gt;&lt;br /&gt;After many tests on my side, I got confirmation from &lt;a href="http://forums.macrumors.com/showthread.php?t=573616" target="_self"&gt;this page&lt;/a&gt;&amp;#0160;: it looks like ulimit doesn&amp;#39;t work for memory limitation starting from Mac OS 10.5. That&amp;#39;s a shame...&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: &amp;#39;andale mono&amp;#39;, times;"&gt;perl -E &amp;#39;use BSD::Resource; &amp;#0160;setrlimit(RLIMIT_VMEM, 2000, 2000); my $s; for my $i (1..50_000) { $s .= &amp;quot;A&amp;quot; x 1024 } say &amp;quot;damned, I should have been killed&amp;quot;&amp;#39;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;#0160;&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/S5zevsGTv7E" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/10/06/ulimit-doesn-t-work-on-leopard-memory-limitation-.html</feedburner:origLink></entry>
 
 <entry>
   <title>Merge PDFs easily with Perl</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/y9TDs5iNyHE/merge-pdfs-easily-with-perl.html" />
   <updated>2010-06-29T00:00:00-07:00</updated>
   <id>http://dams.github.com/2010/06/29/merge-pdfs-easily-with-perl</id>
   <content type="html">&lt;p&gt;Today I discovered an easy way to merge PDFs files using Perl.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In my current project, I have to automatically generate a technical documentation from my perl modules PODs. It&amp;#39;s easy to create one PDF file for each modules, but then I need to merge them all in one.&lt;/p&gt;

&lt;p&gt;The very easy to use CAM::PDF Perl module provides &lt;a href="http://search.cpan.org/%7Ecdolan/CAM-PDF-1.52/bin/appendpdf.pl" title="appelpdf.pl on CPAN"&gt;appendpdf.pl&lt;/a&gt;. However it can only merge 2 files together.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve copied and modified it for my need, and renamed it &lt;span style="font-family: Courier;"&gt;mergepdf.pl&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Download : &lt;span class="asset asset-generic at-xid-6a0120a63366ed970b01348515fed6970c"&gt;&lt;a href="http://damien.krotkine.com/files/mergepdf.pl" title="merge.pl script"&gt;mergepdf.pl&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Usage :&amp;#0160; &lt;span style="font-family: Courier;"&gt;appendpdf.pl [options] file1.pdf file2.pdf ... fileN.pdf outfile.pdf&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;See the help for more options.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/y9TDs5iNyHE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/06/29/merge-pdfs-easily-with-perl.html</feedburner:origLink></entry>
 
 <entry>
   <title>flagedit</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/8y9VYRQTWzc/flagedit.html" />
   <updated>2010-03-29T00:00:00-07:00</updated>
   <id>http://dams.github.com/2010/03/29/flagedit</id>
   <content type="html">&lt;h2&gt;Description&lt;/h2&gt;

&lt;p&gt;
flagedit is a CLI USE flag editor for Gentoo Linux. It let you edit the 
use flags of /etc/make.conf, as well as the /etc/portage/package.use 
file.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="text-decoration: underline;"&gt;features : &lt;/span&gt;


&lt;ul&gt;
&lt;li&gt;edit system use flags (in /etc/make.conf)&lt;/li&gt;
&lt;li&gt;edit per package use flags (in /etc/portage/package.use)&lt;/li&gt;
&lt;li&gt;edit system keyword (ACCEPT_KEYWORDS in /etc/make.conf)&lt;/li&gt;
&lt;li&gt;edit per package keywords (in /etc/portage/package.keywords)&lt;/li&gt;
&lt;li&gt;get the list of possible use flags, and keywords, with their 
descriptions&lt;/li&gt;
&lt;li&gt;flagedit warns you when you try to edit a flag or keyword that 
doesn't exist&lt;/li&gt;
&lt;li&gt;you can specify alternates files for package.use package.keywords 
make.conf&lt;/li&gt;
&lt;li&gt;it creates a backup before overwriting&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;News&lt;/h2&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2009.01.16&lt;/span&gt; Version 0.0.8. make flagedit compatible with directories support ( as per &lt;a href="http://bugs.gentoo.org/241668"&gt;bug 241668&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2005.12.26&lt;/span&gt; Version 0.0.7. The help fits in 80 columns
&lt;/p&gt;

&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2005.11.24&lt;/span&gt; Version 0.0.6. some improvments
&lt;/p&gt;

&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2005.11.15&lt;/span&gt; Version 0.0.5. some improvments
&lt;/p&gt;

&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2005.10.14&lt;/span&gt; Version 0.0.2. An ebuild is available for 
gentoo linux.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2005.09.29&lt;/span&gt; New version : now warns if the flag is not a valid
 one. More features also&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;2005.07.24&lt;/span&gt; just did this web page.&lt;/p&gt;

&lt;br&gt;
&lt;h2&gt;Download&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://damien.krotkine.com/flagedit/download"&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;br&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;p&gt;This is just the raw output of flagedit --help, but I think it's 
self-explanatory :
&lt;/p&gt;&lt;pre&gt;flagedit allows you to edit the use flags or the keywords for a particular&lt;br&gt;ebuild, or for the whole system. a backup is done for each modified file, named&lt;br&gt;file.old.&lt;br&gt;&lt;br&gt;Usage: flagedit [PACKAGE] [ACTIONS | -- KEYWORD_ACTIONS] [ OPTIONS ]&lt;br&gt;&lt;br&gt;Examples:&lt;br&gt; flagedit net-im/amsn --show # shows the use flag set for net-im/amsn&lt;br&gt; flagedit net-im/amsn +gnome # adds the gnome use flag to net-im/amsn&lt;br&gt; flagedit net-im/amsn -kde +xmms # adds the xmms use flag and set the -kde one&lt;br&gt; flagedit net-im/amsn %kde # reset the kde use flag (it's removed from the line)&lt;br&gt;&lt;br&gt; flagedit %kde # reset the global use flag (it's removed in make.conf)&lt;br&gt; flagedit +gnome -qt # add gnome and -qt in make.conf&lt;br&gt;&lt;br&gt; flagedit net-im/amsn -- %x86 # reset the x86 keyword for net-im/amsn&lt;br&gt; flagedit net-im/amsn -- +~ppc +~x86 # adds the ~ppc and ~x86 keywords for net-im/amsn&lt;br&gt; flagedit net-im/amsn -- % # resets the keywords for this package&lt;br&gt; flagedit -- +~x86 # sets ACCEPT_KEYWORDS to "~x86" in /etc/make.conf&lt;br&gt;&lt;br&gt;You can mix the flags and keywords :&lt;br&gt; flagedit net-im/amsn +gnome -- +~x86&lt;br&gt;&lt;br&gt;PACKAGE is a package name (like dev-ruby/ruby-atk). If no package is given,&lt;br&gt;flagedit will edit the maine USE flags (in make.conf), or the main&lt;br&gt;ACCEPT_KEYWORDS (in make.conf)&lt;br&gt;&lt;br&gt;ACTIONS are :&lt;br&gt;+FLAG enable the FLAG. Example : +sse&lt;br&gt;-FLAG disable the FLAG. Example : -sse&lt;br&gt;%FLAG reset the FLAG to default. Example : %sse&lt;br&gt;% reset the whole flags of PACKAGE to default. In this case, PACKAGE is not optional&lt;br&gt;&lt;br&gt;KEYWORD_ACTIONS are :&lt;br&gt;+KEYWORD enable the keyword. Example : +x86&lt;br&gt;-KEYWORD disable the KEYWORD. Example : -~x86&lt;br&gt;%KEYWORD reset the KEYWORD to default. Example : %x86&lt;br&gt;% reset the whole keywords of PACKAGE to default. In this case, PACKAGE is not optional&lt;br&gt;&lt;br&gt;&lt;br&gt;OPTIONS are :&lt;br&gt; --package-file &amp;lt;path&amp;gt; specify an alternate package.use file (default is /etc/portage/package.use)&lt;br&gt; --keywords-file &amp;lt;path&amp;gt; specify an alternate package.keywords file (default is /etc/portage/package.keywords)&lt;br&gt; --make-conf-file &amp;lt;path&amp;gt; specify an alternate make.conf file (default is /etc/make.conf)&lt;br&gt; --portage-dir &amp;lt;path&amp;gt; specify an alternate portage directory path (default is /usr/portage)&lt;br&gt; --alpha-order sort the flags or keywords alphabetically instead of keeping the original order&lt;br&gt; --show don't edit, display the flags or keywords of the PACKAGE. If no package is given, display the system USE flags or the system ACCEPT_KEYWORDS.&lt;br&gt; --list don't edit, display the entire list of possible flags or possible keywords.&lt;br&gt; --desc if specified with --list, display the flags or keywords description also.&lt;br&gt; --keywords specifies that actions are to be done on keywords, not on use flags&lt;br&gt; -- same as --keywords&lt;br&gt; --strict if a specified flag or keyword name is invalid, dies, instead of just warning.&lt;br&gt; --nowarn if a specified flag or keyword name is invalid, don't warn.&lt;br&gt; --help this help&lt;br&gt; --version prints the version&lt;br&gt; &lt;br&gt;see http://dkrotkine.com/flagedit/&lt;br&gt;&lt;/pre&gt;

&lt;br&gt;
&lt;h2&gt;About&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;author : &lt;a href="http://damien.krotkine.com"&gt;dams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;license : GPL-2 (not upper version)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Thanks to&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tigger for requesting it, and testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/8y9VYRQTWzc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/03/29/flagedit.html</feedburner:origLink></entry>
 
 <entry>
   <title>Syntax Highlighting in Typepad</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/rV-C-vuw6vw/syntax-highlighting-in-typepad.html" />
   <updated>2010-03-15T00:00:00-07:00</updated>
   <id>http://dams.github.com/2010/03/15/syntax-highlighting-in-typepad</id>
   <content type="html">&lt;p&gt;&lt;/p&gt;&lt;h1&gt;Code Snippets, Syntax Highlighting, Source examples, Verbatim text, etc...&lt;/h1&gt;I&amp;#39;m sure I&amp;#39;m not the only one to need to display nice clean and compatible code snippets, source code examples, and similar stuff. I&amp;#39;m using Typepad as blog engine, but what I&amp;#39;ll explain here should work with MovableType as well (as the former is a professional version of the open source latter one).&lt;p&gt;First of all, the needs :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I need a tool to display code snippets, examples,&lt;/li&gt;
&lt;li&gt;It has to be easy to use,&lt;/li&gt;
&lt;li&gt;It has to be nice&lt;/li&gt;
&lt;li&gt;It should have syntax highlighting and coloring&lt;/li&gt;
&lt;li&gt;It has to support Perl, Javascript, and ruby syntax&lt;/li&gt;
&lt;li&gt;It has to allow download and view as text&lt;/li&gt;
&lt;li&gt;It has to degrade properly, so that it works in RSS clients&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The solution is of course &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;SyntaxHighlighter&lt;/a&gt;, the well known tool by &lt;a href="http://alexgorbatchev.com"&gt;Alex Gorbatchev&lt;/a&gt;. This tool is used &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Spotlight"&gt;widely &lt;/a&gt;and some people have already written on &lt;a href="http://www.jontesays.com/jonte-says/2009/03/adding-syntaxhighlighter-to-a-typepad-pro-account-using-advanced-templates.html"&gt;including it in Movable Type&lt;/a&gt;, or even &lt;a href="http://www.jontesays.com/jonte-says/2009/03/adding-syntaxhighlighter-to-a-typepad-pro-account-using-advanced-templates.html"&gt;in Typepad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But I thought I would write on it as well, because there are some subtleties, and both SyntaxHighlighter and Typepad evolved since these entries were created.&lt;/p&gt;

&lt;p&gt;So, if you don&amp;#39;t know this too yet, or are too lazy to check its description page, SyntaxHighlighter is a pure JavaScript + CSS tool that finds and renders content, from a specific standard HTML tag you specify.&amp;#0160;&lt;/p&gt;

&lt;h1&gt;Example&lt;/h1&gt;

&lt;p&gt;&lt;code class="brush: perl"&gt;
# Some Perl code&lt;br /&gt;
my $var = 42;&lt;br /&gt;
my @array = map { reverse }&lt;br /&gt;
 grep { length }&lt;br /&gt;
 @strings;&lt;br /&gt;&lt;br /&gt;

sub my_function {&lt;br /&gt;
 my ($a, $b) = @_;&lt;br /&gt;
 return ($a * $b);&lt;br /&gt;
}
&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;Download&lt;/h1&gt;&lt;p&gt;First of all, you &lt;strong&gt;don&amp;#39;t&lt;/strong&gt; want to download SyntaxHighlighter 
from it &amp;quot;&lt;em&gt;official&lt;/em&gt;&amp;quot; google code home, &lt;span style="text-decoration: line-through;"&gt;because it&amp;#39;s hosted by Google&lt;/span&gt;
 (sorry, just kidding) because only the version 1.5 is available there. 
What we want is &lt;strong&gt;version 2.0&lt;/strong&gt;, which has more features, and 
includes a Perl syntax &lt;em&gt;brush&lt;/em&gt; by default (so no need to get it 
from elsewhere).&lt;/p&gt;

&lt;p&gt;Download SyntaxHighlighter from &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Download" title="download page for SyntaxHighlighter"&gt;this page&lt;/a&gt;. I downloaded version &lt;a href="http://alexgorbatchev.com/downloads/grab.php?name=sh" title="version 2.1.364 of SyntaxHighlighter"&gt;2.1.364&lt;/a&gt; (&lt;a href="http://damien.krotkine.com/files/syntaxhighlighter_2.1.364.zip" title="version 2.1.364 of SyntaxHighlighter"&gt;local copy here&lt;/a&gt; in case the site is down)&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h1&gt;Upload to your TypePad Account&lt;/h1&gt;Next, you need to upload the files to your TypePad File Manager. You&amp;#39;ll find it in the Library Tab.&lt;br /&gt;&lt;p&gt;&lt;a href="http://damien.krotkine.com/.a/6a0120a63366ed970b0120a93a0550970b-pi" onclick="window.open(this.href,&amp;#39;_blank&amp;#39;,&amp;#39;scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0&amp;#39;);
 return false" style="display: inline;"&gt;&lt;img alt="Image 9" class="asset asset-image 
at-xid-6a0120a63366ed970b0120a93a0550970b " src="http://damien.krotkine.com/.a/6a0120a63366ed970b0120a93a0550970b-320pi" style="margin: 0pt;" title="Image 9" /&gt;&lt;/a&gt;&amp;#0160; &lt;/p&gt;

&lt;p&gt;Then create a directory (I created mine as &lt;em&gt;syntaxhighlighter&lt;/em&gt; at the root), and upload the following files. This list is the bare minimum to have it working, but you can (you should) add more &lt;em&gt;brush&lt;/em&gt;es to support more languages highlighting, and also upload the icons (the .png files). You could as well upload all the languages brushes. And you can also use a different theme (I&amp;#39;ll try the Emacs one, as I&amp;#39;m an Emacs addict).&lt;/p&gt;

&lt;p&gt;&amp;#0160; &lt;a href="http://damien.krotkine.com/.a/6a0120a63366ed970b0120a93a094e970b-popup" onclick="window.open(this.href,&amp;#39;_blank&amp;#39;,&amp;#39;scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0&amp;#39;);

 return false" style="display: inline;"&gt;&lt;img alt="Image 7" class="asset 
asset-image at-xid-6a0120a63366ed970b0120a93a094e970b 
 " src="http://damien.krotkine.com/.a/6a0120a63366ed970b0120a93a094e970b-320wi" style="margin: 0pt;" title="Image 7" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Make sure your upload works by trying to access one of the file (of course replace your real site host name) :&lt;/p&gt;

&lt;p&gt;http://YOURSITE.COM/syntaxhighlighter/shCore.js&lt;/p&gt;

&lt;p&gt;If you can see or download the file, it means the files are properly uploaded.&lt;/p&gt;&lt;h1&gt;Add some magic&lt;/h1&gt;&lt;p&gt;For SyntaxHighlighter to work, you need to include some Javascript and CSS to the pages that will contain things you want to highlight. The best is to include it on every pages, as the tool is smart enough to find and apply styling only on what you specify to be highlighted.&lt;/p&gt;

&lt;p&gt;Now, how do you add CSS and Javascript to your TypePad blog? There are two cases :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Either you are using a &lt;strong&gt;simple TypePad design&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Or you are using an &lt;strong&gt;advanced TypePad design&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All blog entries I&amp;#39;ve seen on this topic only handles the case of &lt;strong&gt;advanced&lt;/strong&gt; design, because it&amp;#39;s easier to do. But, people using advanced design don&amp;#39;t need a tutorial to include SyntaxHighlighter on their blog, they are, you know, &lt;em&gt;advanced&lt;/em&gt; enough to do it on their own... So I thought it would be &lt;em&gt;more useful&lt;/em&gt; to describe how to do with a simple design.&lt;/p&gt;

&lt;p&gt;With a simple design on TypePad, you don&amp;#39;t have access to the templates of the pages, but luckily, you can add a module that allows you to add any HTML code in your page. So the idea is to this module to your design content, and add the needed javascript and CSS reference to it. Here is how you can do it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From your TypePad dashboard, go to &lt;strong&gt;Design&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Content&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add a new module, called &amp;quot;&lt;em&gt;Embed your own HTML&lt;/em&gt;&amp;quot; (see picture)&lt;/li&gt;
&lt;li&gt;Give it a name (it&amp;#39;s not used in the page, it&amp;#39;s just to see what this module is here for).&lt;/li&gt;
&lt;li&gt;Be sure that you move the module to be on the lowest part of your blog content (to be loaded last)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;#0160;&lt;a href="http://damien.krotkine.com/.a/6a0120a63366ed970b01310fa186af970c-popup" onclick="window.open( this.href, &amp;#39;_blank&amp;#39;, &amp;#39;width=640,height=480,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0&amp;#39; ); return false" style="display: inline;"&gt;&lt;img alt="Image 10" class="asset asset-image at-xid-6a0120a63366ed970b01310fa186af970c " src="http://damien.krotkine.com/.a/6a0120a63366ed970b01310fa186af970c-320wi" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The content of the module will be used to load SyntaxHighlighter. Here is what I input in the module :&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;
&lt;code class="brush: xml"&gt;
&amp;lt;!-- Include required JS files --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://YOURSITE.com&lt;br /&gt;/syntaxhighlighter/shCore.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- At least one brush, here we choose Perl.--&amp;gt;&lt;br /&gt;
&amp;lt;!-- You need to include a brush for every language you want to highlight --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://YOURSITE.com&lt;br /&gt;/syntaxhighlighter/shBrushPerl.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Include *at least* the core style and default theme --&amp;gt;&lt;br /&gt;
&amp;lt;!-- You can choose a different theme --&amp;gt;&lt;br /&gt;
&amp;lt;link href=&amp;quot;http://YOURSITE.com/syntaxhighlighter/shCore.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;link href=&amp;quot;http://YOURSITE.com/syntaxhighlighter/shThemeDefault.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Important options, and finally the main call --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
 SyntaxHighlighter.config.tagName = &amp;quot;code&amp;quot; // use &amp;lt;code&amp;gt; tags&lt;br /&gt;
 SyntaxHighlighter.config.stripBrs = true&amp;#0160; // disregard trailing &amp;lt;br&amp;gt;&lt;br /&gt;
 SyntaxHighlighter.all()&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;The Options&lt;/h1&gt;
&lt;p&gt;As you can see, there are 2 options set at the end. These options are to make SyntaxHighlighter more compatible with the TypePad graphical editor. By default, SyntaxHighlighter looks for &lt;strong&gt;&amp;lt;pre&amp;gt;&lt;/strong&gt; tags. But these are rebuilt each time you modify an entry in the graphical editor. So one of the option is to be able to use &lt;strong&gt;&amp;lt;code&amp;gt;&lt;/strong&gt; tags, that are left untouched by TypePad. Well, almost untouched, TypePad tends to add &lt;strong&gt;&amp;lt;br&amp;gt;&lt;/strong&gt; tags at the end of line, which is why the seconde option is there.&lt;/p&gt;

&lt;h1&gt;Include your code snippet in TypePad&lt;/h1&gt;

&lt;p&gt;Now that everything is setup, all there is to do to have a nice code example into TypePad is to create a new Post, write the text using the &amp;quot;&lt;em&gt;Rich Text&lt;/em&gt;&amp;quot; view of the editor. Then when you want to include a code snippet, switch to the &amp;quot;&lt;em&gt;HTML&lt;/em&gt;&amp;quot; view, and add this :&lt;/p&gt;

&lt;p&gt;
&lt;code class="brush: xml"&gt;
&amp;lt;code class=&amp;quot;brush: perl&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
# Your code example goes here. For instance, some Perl :&amp;lt;br&amp;gt;&lt;br /&gt;
my %hash = { foo =&amp;gt; &amp;#39;bar&amp;#39; };&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;

&lt;p&gt;Which will output on your blog page as :&lt;/p&gt;

&lt;p&gt;&lt;code class="brush: perl"&gt;
# Your code example goes here. For instance, some Perl :&lt;br /&gt;
my %hash = { foo =&amp;gt; &amp;#39;bar&amp;#39; };&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;&lt;p&gt;

And inside the TypePad graphical editor, this is what you will see. Most of the Atom / RSS feeds client (like Google Reader) will also have it like this : &lt;/p&gt;&lt;p&gt;&amp;#0160;&lt;a href="http://damien.krotkine.com/.a/6a0120a63366ed970b01310fa1a77f970c-popup" onclick="window.open( this.href, &amp;#39;_blank&amp;#39;, &amp;#39;width=640,height=480,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0&amp;#39; ); return false" style="display: inline;"&gt;&lt;img alt="Image 11" class="asset asset-image at-xid-6a0120a63366ed970b01310fa1a77f970c " src="http://damien.krotkine.com/.a/6a0120a63366ed970b01310fa1a77f970c-320wi" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;/p&gt;&lt;p&gt;Which is in my opinion, not too bad !&lt;/p&gt;&lt;h1&gt;Conclusion&lt;/h1&gt;&lt;p&gt;So here it is : a nice, free and open source syntax highlighter in your TypePad posts, easily included, wich themes, colors, a lot of languages supported, and which degrades nicely for feeds readers. There is more customization possible, I suggest you go look at the SyntaxHighlighter documentation.&lt;/p&gt;&lt;p&gt;I have tried to make this post / tutorial as easy as I possible, but please let me know if you think I should clear ups things, or add more screenshots. If you try to do it on your TypePad account and it works, let me know in the comment. If it doesn&amp;#39;t work, I&amp;#39;ll try to help.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/rV-C-vuw6vw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/03/15/syntax-highlighting-in-typepad.html</feedburner:origLink></entry>
 
 <entry>
   <title>Typepad</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/fqRbm4QEMtk/typepad.html" />
   <updated>2010-03-05T00:00:00-08:00</updated>
   <id>http://dams.github.com/2010/03/05/typepad</id>
   <content type="html">&lt;p&gt;I&amp;#39;m in the metro of Paris, testing Typepad :&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;new beta account I just subscribed to&lt;/li&gt;
&lt;li&gt;new mobile version of the blog&lt;/li&gt;
&lt;li&gt;Iphone App&lt;/li&gt;
&lt;li&gt;automatic Twitter posting&lt;/li&gt;
&lt;li&gt;per category feeds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Typepad is Based on Movable Type, the best blog system ouuta there. It&amp;#39;s Perl based. It rocks. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/fqRbm4QEMtk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2010/03/05/typepad.html</feedburner:origLink></entry>
 
 <entry>
   <title>Perl tests in Hudson via JUnit</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/2d5QzXpwq78/perl-tests-in-hudson-via-junit.html" />
   <updated>2009-11-25T00:00:00-08:00</updated>
   <id>http://dams.github.com/2009/11/25/perl-tests-in-hudson-via-junit</id>
   <content type="html">&lt;p&gt;&lt;/p&gt;&lt;h2&gt;Perl tests in Hudson&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m willing to automate the unit testing of my Perl modules, by plugging them into &lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt;. Hudson is a continuous integration server, it &amp;quot;&lt;em&gt;monitors executions of repeated jobs, such as building a software project or jobs run by cron&lt;/em&gt;&amp;quot;. It works well, is extensible, and looks good.&lt;/p&gt;

&lt;p&gt;So, The easiest way to do that is have Hudson to execute the module test suite, and look at the output. Actually, not really the output, but a file containing the output of the tests, in &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt; format.&lt;/p&gt;

&lt;p&gt;Now, by default, Perl unit tests doesn&amp;#39;t output JUnit. You know, that kind of stuff :&lt;/p&gt;

&lt;script src="http://gist.github.com/242615.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;That&amp;#39;s the standard output of tests run through TAP, the &lt;a href="http://testanything.org/wiki/index.php/Main_Page"&gt;Test Anything Protocol&lt;/a&gt;, which is great, and (imho) better than JUnit.&lt;/p&gt;

&lt;p&gt;Anyway, that output is generated because the tests are run through &lt;a href="http://search.cpan.org/perldoc?TAP::Harness"&gt;TAP::Harness&lt;/a&gt;, that outputs the result in TAP format on the console.&lt;/p&gt;

&lt;p&gt;So first of all, let&amp;#39;s see how to transform the tests output into JUnit. My modules use &lt;a href="http://search.cpan.org/perldoc?Module::Build"&gt;Module::Build&lt;/a&gt; (and also &lt;a href="http://search.cpan.org/perldoc?Dist::Zilla"&gt;Dist::Zilla&lt;/a&gt;, but that&amp;#39;s an other story) as building and releasing system. When using Module::Build, running the test suite is easy :&lt;/p&gt;

&lt;script src="http://gist.github.com/242619.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;h2&gt;Solution 1 : use TAP::Formatter::JUnit&lt;/h2&gt;

&lt;p&gt;After some research and looking in the source code, I discovered that you can pass a lot of options to TAP::Harness, via Module::Build. Especially, you can specify a formatter to TAP::Harness when running the test suite. TAP formatters are modules that all inherit of TAP::Formatter::Base.&lt;/p&gt;

&lt;p&gt;For instance, if instead of outputing the result on the console, you want it to be stored in a file, use &lt;a href="http://search.cpan.org/perldoc?TAP::Formatter::File"&gt;TAP::Formatter::File&lt;/a&gt;. As you may have guessed now, there is a formatter that outputs JUnit : &lt;a href="http://search.cpan.org/perldoc?TAP::Formatter::JUnit"&gt;TAP::Formatter::Junit&lt;/a&gt;. That&amp;#39;s exactly what we want. By issuing the following command line, the output of the test suite is in JUnit format.&lt;/p&gt;

&lt;script src="http://gist.github.com/242627.js?file=gistfile1.sh"&gt;&lt;/script&gt;&lt;p&gt;

 Now we just need to tell Hudson to run it and look at the output &lt;/p&gt;

&lt;h2&gt;Solution 2 : use TAP::Harness::JUnit&lt;/h2&gt;

&lt;p&gt;For some reasons, I had some trouble with TAP::Formatter::Junit on windows, mainly because there is no ActiveState PPM for this package. So I decided to give a go with &lt;a href="http://search.cpan.org/dist/TAP-Harness-JUnit/"&gt;TAP::Harness::JUnit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its documentation is self-explanatory : it&amp;#39;s a child class of TAP::Harness, that accepts an xml file name as argument, and procudes directly a JUnit output. This module being directly available in ActiveState Perl, it seemed to be aa good approach.&lt;/p&gt;

&lt;p&gt;So the goal is to replace the call to TAP::Harness into TAP::Harness::JUnit, when doing Build test. And actually, it would be better to have an additional action to Build, so that we could do Build test, and Build hudson_test.&lt;/p&gt;

&lt;p&gt;Luckily, Module::Build makes it easy to add an action. By looking at the ACTION_test method in Module::Build::Base, it&amp;#39;s easy to see what needs to be changed. See this code snippet. What we want is a copy of that code that would run TAP::Harness::JUnit instead of TAP::Harness.&lt;/p&gt;

&lt;script src="http://gist.github.com/242842.js?file=gistfile1.pl"&gt;&lt;/script&gt;

&lt;p&gt;After some work, here is what I eneded with. This code is to be added into your Build.PL.&lt;/p&gt;

&lt;script src="http://gist.github.com/242852.js?file=gistfile1.pl"&gt;&lt;/script&gt;

&lt;p&gt;Now, build and run your tests in hudson mode&lt;/p&gt;

&lt;script src="http://gist.github.com/242855.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;h2&gt;Configure Hudson&lt;/h2&gt;

&lt;p&gt;That&amp;#39;s the easiest part : Setup a new project, add as execution line &amp;quot;&lt;span style="font-family: Courier;"&gt;perl Build.PL &amp;amp; Build hudson_test&lt;/span&gt;&amp;quot; (if you are on a windows hudson node). And point the project to the output file called &amp;quot;hudson_test_output.xml&amp;quot;. That&amp;#39;s it !&lt;/p&gt;&lt;p&gt;&lt;a href="http://damien.krotkine.com/.a/6a0120a63366ed970b012875d92f9e970c-popup" onclick="window.open( this.href, &amp;#39;_blank&amp;#39;, &amp;#39;width=640,height=480,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0&amp;#39; ); return false" style="display: inline;"&gt;&lt;img alt="Image 57" class="asset asset-image at-xid-6a0120a63366ed970b012875d92f9e970c " src="http://damien.krotkine.com/.a/6a0120a63366ed970b012875d92f9e970c-320wi" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/2d5QzXpwq78" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2009/11/25/perl-tests-in-hudson-via-junit.html</feedburner:origLink></entry>
 
 <entry>
   <title>Curses Toolkit is on CPAN</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/MqGOwhXPiN4/curses-toolkit-is-on-cpan.html" />
   <updated>2009-10-31T00:00:00-07:00</updated>
   <id>http://dams.github.com/2009/10/31/curses-toolkit-is-on-cpan</id>
   <content type="html">&lt;p&gt;After few months of delay, &lt;a href="http://search.cpan.org/perldoc?Curses::Toolkit" title="Curses::Toolkit on CPAN"&gt;Curses::Toolkit is now available on CPAN&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Curses::Toolkit tries to be a modern toolkit to implement semi-graphical interfaces using Curses. It&amp;#39;s inspired by Gtk.&lt;/p&gt;&lt;p&gt;I gave a presentation of Curses::Toolkit at the &lt;a href="http://conferences.mongueurs.net/fpw2009/" title="FPW&amp;#39;09"&gt;French Perl Workshop 2009&lt;/a&gt;, and at the &lt;a href="http://act.osdc.fr/osdc2009fr/"&gt;Open Source Developers conference France 2009&lt;/a&gt;. BooK presented it as part of a Lightning Talk at &lt;a href="http://yapceurope2009.org/ye2009/" title="YAPC::EU 2009"&gt;YAPC EU 2009&lt;/a&gt; where I couldn&amp;#39;t participate. Thanks to him for that. I will try to participate to &lt;a href="http://conferences.yapceurope.org/lpw2009/" title="LPW 09"&gt;London Perl Workshop&lt;/a&gt; this year and give a talk about it as well. I have received quite good feedback from people and users about it.&lt;/p&gt;&lt;p&gt;I&amp;#39;d like to mention that &lt;a href="http://jquelin.blogspot.com/" title="Jerome Quelin"&gt;Jerome Quelin&lt;/a&gt; helped me with the initial release, injecting some Dist::Zilla magic into Curses::Toolkit. Thanks, Jerome.&lt;/p&gt;&lt;p&gt;What next ? I&amp;#39;ll try to post a video of what is currently possible with Curses::Toolkit. I need to add more widgets and signals, and fix some bugs. Also, migrating to Moose is on the todo list. The module is usable now, but you can&amp;#39;t really build a very nice big application with it.&lt;/p&gt;&lt;p&gt;Want to help ? If you have some free time, please consider helping me on next development of the module. You don&amp;#39;t need to be a coder, here are some of the things you could help with :&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Improve documentation : current documentation has some errors, and a better front page for the module would be good.&lt;/li&gt;
&lt;li&gt;Create a Tutorial : preferably in POD, but not tied to follow sub-modules&amp;#39; names&lt;/li&gt;
&lt;li&gt;Help implementing additional widgets&lt;/li&gt;
&lt;li&gt;Create new themes : it&amp;#39;s all about colors&lt;/li&gt;
&lt;li&gt;Help the migration to Moose&lt;/li&gt;
&lt;/ul&gt;
If you&amp;#39;re interested, contact me. The source is &lt;a href="http://github.com/dams/curses-toolkit" title="Curses::Toolkit on github"&gt;here&lt;/a&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/MqGOwhXPiN4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2009/10/31/curses-toolkit-is-on-cpan.html</feedburner:origLink></entry>
 
 <entry>
   <title>New Home</title>
   <link href="http://feedproxy.google.com/~r/damien-krotkine/~3/vPoBh1aseb0/new-home.html" />
   <updated>2009-10-29T00:00:00-07:00</updated>
   <id>http://dams.github.com/2009/10/29/new-home</id>
   <content type="html">&lt;p&gt;The new server I had setup few weeks ago got hacked, brute force ssh attacks being made from it... I had spent some time setting it up, and now I&amp;#39;m bored.&lt;/p&gt;&lt;p&gt;So, I decided to migrate my blog to a hosted solution. As I&amp;#39;m a big fan of &lt;a href="http://www.movabletype.org/"&gt;movable type&lt;/a&gt;, I decided to give Typepad a go. So this is yet another rebirth of my blog (I think it&amp;#39;s the 6th time now).&lt;/p&gt;&lt;p&gt;I&amp;#39;ll use that opportunity to catch up with the Perl blogging &lt;a href="http://www.typepad.com/site/blogs/6a0120a63366ed970b0120a689fba3970c/post/compose"&gt;Iron Man&lt;/a&gt; competition.&lt;/p&gt;&lt;p&gt;More to come about Perl and &lt;a href="http://search.cpan.org/perldoc?Curses::Toolkit"&gt;Curses::Toolkit&lt;/a&gt;, my baby :)&lt;/p&gt;&lt;p&gt;&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/damien-krotkine/~4/vPoBh1aseb0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://dams.github.com/2009/10/29/new-home.html</feedburner:origLink></entry>
 
 
</feed>
