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

<channel>
	<title>i'm a lumberjaph</title>
	<atom:link href="http://lumberjaph.net/blog/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://lumberjaph.net/blog</link>
	<description>and i'm ok, i work all night. i sleep all day</description>
	<pubDate>Sun, 07 Mar 2010 18:55:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>github explorer - a preview</title>
		<link>http://lumberjaph.net/blog/index.php/2010/03/07/github-explorer-a-preview/</link>
		<comments>http://lumberjaph.net/blog/index.php/2010/03/07/github-explorer-a-preview/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 18:38:09 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[ironman]]></category>

		<category><![CDATA[github]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=608</guid>
		<description><![CDATA[For the last weeks, I&#8217;ve been working on the successor of CPAN Explorer. This time, I&#8217;ve decided to create some visualizations (probably 8) of the various communities using Github. I&#8217;m happy with the result, and will soon start to publish the maps (statics and interactives) with some analyses. I&#8217;m publishing two previews: the Perl community [...]]]></description>
			<content:encoded><![CDATA[<p>For the last weeks, I&#8217;ve been working on the successor of <a href="http://cpan-explorer.org/">CPAN Explorer</a>. This time, I&#8217;ve decided to create some visualizations (probably 8) of the various communities using <a href="http://github.com/">Github</a>. I&#8217;m happy with the result, and will soon start to publish the maps (statics and interactives) with some analyses. I&#8217;m publishing two previews: the Perl community and the european developers. These are not final results. The colors, fonts, and  layout may change. But the structure of the graphs will be the same. All the data was collected using the <a href="http://develop.github.com/">github API</a>.</p>
<p><a href="http://www.flickr.com/photos/franck_/4413528529/sizes/l/"><img src="http://franck.lumberjaph.net/github-perl-preview.png" alt="the Perl community on github" /></a></p>
<p>Each node on the graph represents a developer. When a developer &#8220;follows&#8221; another developer on github, a link between them is created. The color on the Perl community map represent the countries of the developer. One of the most visible things on this graph is that the japanese community is tighly connected and shares very little contact with the foreign developers. miyagawa obviously acts as a glue between japanese and worldwide Perl hackers.</p>
<p><a href="http://www.flickr.com/photos/franck_/4414287310/sizes/o/in/photostream/"><img src="http://franck.lumberjaph.net/github-europe-preview.png" alt="European developers on github" /></a></p>
<p>The second graph is a little bit more complex. It represents the European developers on github. Here the colors represent the languages used by the developers. It appears that ruby is by far the most represented language on github, as it dominates the whole map. Perl is the blue cluster at the bottom of the map, and the green snake is&#8230; Python.</p>
<p>Thanks to <a href="http://code.google.com/p/tinyaml/">bl0b</a> for his suggestions :)</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2010/03/07/github-explorer-a-preview/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SD and github</title>
		<link>http://lumberjaph.net/blog/index.php/2010/02/03/sd-and-github/</link>
		<comments>http://lumberjaph.net/blog/index.php/2010/02/03/sd-and-github/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 08:12:45 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[ironman]]></category>

		<category><![CDATA[github]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[sd]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=605</guid>
		<description><![CDATA[If you are using the version of SD hosted on github, you can now clone and pull issues very easily. First,

$ git config --global github.user franckcuny
$ git config --global github.token myapitoken

This will set in your .gitconfig your github username and api token. Now, when you clone or pull some issues using sd:

$ git sd clone [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using the version of <a href="http://syncwith.us/">SD</a> hosted on <a href="http://github.com/bestpractical/sd">github</a>, you can now clone and pull issues very easily. First,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">$ git config <span style="color: #660033;">--global</span> github.user franckcuny
$ git config <span style="color: #660033;">--global</span> github.token myapitoken</pre></div></div>

<p>This will set in your <strong>.gitconfig</strong> your github username and api token. Now, when you clone or pull some issues using sd:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">$ git sd clone <span style="color: #660033;">--from</span> github:sukria<span style="color: #000000; font-weight: bold;">/</span>Dancer</pre></div></div>

<p>sd will check your .gitconfig to find your credentials.</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2010/02/03/sd-and-github/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dancer 1.130</title>
		<link>http://lumberjaph.net/blog/index.php/2010/01/31/dancer-1130/</link>
		<comments>http://lumberjaph.net/blog/index.php/2010/01/31/dancer-1130/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 11:38:32 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[ironman]]></category>

		<category><![CDATA[dancer]]></category>

		<category><![CDATA[framework]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=584</guid>
		<description><![CDATA[Alexis (sukria) released Dancer 1.130 this weekend. Dancer is a small and nice web framework based on ruby&#8217;s sinatra.
Dancer have few dependancies (and it doesn&#8217;t depends anymore on CGI.pm). The path dispatching is done using rules declared with HTTP methods (get/post/put/delete), and they are mapped to a sub-routine which is returned as the response to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.sukria.net/fr/">Alexis</a> (<a href="http://search.cpan.org/~sukria/">sukria</a>) released <a href="http://search.cpan.org/perldoc?Dancer">Dancer</a> 1.130 this weekend. Dancer is a small and nice web framework based on ruby&#8217;s <a href="http://www.sinatrarb.com/">sinatra</a>.</p>
<p>Dancer have few dependancies (and it doesn&#8217;t depends anymore on CGI.pm). The path dispatching is done using rules declared with HTTP methods (get/post/put/delete), and they are mapped to a sub-routine which is returned as the response to the request. Sessions are supported, and two template engines (one of them is Template Toolkit) comes with the Core. Dancer::Template::MicroTemplate is also available on CPAN if you need a light template engine.</p>
<p>You can easily test it with a simple script</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/env perl</span>
<span style="color: #000000; font-weight: bold;">use</span> Dancer;
&nbsp;
get <span style="">'/'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066;">return</span> <span style="color: #ff0000;">&quot;dancer&quot;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
get <span style="">'/:name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066;">return</span> params<span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>name<span style="color: #009900;">&#125;</span> .<span style="color: #ff0000;">&quot; is dancing&quot;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
dance;</pre></div></div>

<p>and execute this script, point your browser to http://127.0.0.1:3000, and voila.</p>
<p>Dancer provides also a small helper to write a new application:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">dancer <span style="color: #660033;">-a</span> MyApplication</pre></div></div>

<p>If you create an application with this script, an <strong>app.psgi</strong> file will be created. You can now execute <strong>plackup &#8211;port 8080 </strong> (which comes with <a href="http://search.cpan.org/perldoc?Plack">Plack</a> the <a href="http://plackperl.org/">Perl Web Server</a>) and test if everything works fine:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">curl http:<span style="color: #000000; font-weight: bold;">//</span>localhost:<span style="color: #000000;">8080</span></pre></div></div>

<p>This release remove some components from the core and they are now available as differents CPAN distributions. Two new keyword have also been added, <strong>header</strong> and <strong>prefix</strong>.</p>
<p>If you want to read more about Dancer:</p>
<ul>
<li>
<a href="http://search.cpan.org/perldoc?Dancer">Dancer&#8217;s documentation</a>
</li>
<li>
<a href="http://blogs.perl.org/users/sawyer_x/2010/01/i-gotz-me-a-dancer.html">rewiew by xsawyerx</a>
</li>
<li>
<a href="http://gugod.org/2009/12/dancer.html">gugod&#8217;s review</a>
</li>
<li>
<a href="http://www.sukria.net/fr/archives/tag/dancer/">sukria&#8217;s blog</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2010/01/31/dancer-1130/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tatsumaki, or how to write a nice webapp in less than two hours</title>
		<link>http://lumberjaph.net/blog/index.php/2009/12/21/tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/12/21/tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 21:49:21 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[apps]]></category>

		<category><![CDATA[ironman]]></category>

		<category><![CDATA[lifestream]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[Tatsumaki]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=573</guid>
		<description><![CDATA[Until today, I had a script named &#8220;lifestream.pl&#8221;. This script was triggered via cron once every hour, to fetch various feeds from services I use (like github, identi.ca, &#8230;) and to process the result through a template and dump the result in a HTML file.
Today I was reading Tatsumaki&#8217;s code and some examples (Social and [...]]]></description>
			<content:encoded><![CDATA[<p>Until today, I had a script named &#8220;lifestream.pl&#8221;. This script was triggered via cron once every hour, to fetch various feeds from services I use (like <a href="http://github.com/">github</a>, <a href="http://identi.ca/">identi.ca</a>, &#8230;) and to process the result through a template and dump the result in a HTML file.</p>
<p>Today I was reading <a href="http://github.com/miyagawa/Tatsumaki">Tatsumaki&#8217;s code</a> and some examples (<a href="http://github.com/gugod/Social">Social</a> and <a href="http://github.com/miyagawa/Subfeedr">Subfeedr</a>). Tatsumaki is a &#8220;port&#8221; <a href="http://www.tornadoweb.org/">tornado</a> (a non blocking server in Python), based on Plack and AnyEvent. I though that using this to replace my old lifestream script would be a good way to test it. Two hours later I have a complete webapp that works (and the code is available <a href="http://github.com/franckcuny/lifestream">here</a>).</p>
<p>The code is really simple: first, I define an handler for my HTTP request. As I have only one things to do (display entries), the handler is really simple:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> Lifestream<span style="color: #339933;">::</span><span style="color: #006600;">Handler</span>;   
<span style="color: #000000; font-weight: bold;">use</span> Moose;                     
extends <span style="">'Tatsumaki::Handler'</span>;  
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> get <span style="color: #009900;">&#123;</span>                      
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span>;          
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%params</span> <span style="color: #339933;">=</span> <span style="color: #339933;">%</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">request</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">params</span><span style="color: #009900;">&#125;</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">render</span><span style="color: #009900;">&#40;</span> <span style="">'lifestream.html'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        memes    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">application</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">memes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$params</span><span style="color: #009900;">&#123;</span>page<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        services <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">application</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">services</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
<span style="color: #cc66cc;">1</span>;</pre></div></div>

<p>For all the get request, 2 methods are called : <strong>memes</strong> and <strong>services</strong>. The <strong>memes</strong> get a list of memes to display on the page. The services get the list of the various services I use (to display them on a sidebar). </p>
<p>Now, as I don&#8217;t want to have anymore my lifestream.pl script in cron, I will let Tatsumaki do the polling. For this, I add a service to my app, which is just a worker.</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> Lifestream<span style="color: #339933;">::</span><span style="color: #006600;">Worker</span>;    
<span style="color: #000000; font-weight: bold;">use</span> Moose;                     
extends <span style="">'Tatsumaki::Service'</span>;  
<span style="color: #000000; font-weight: bold;">use</span> Tatsumaki<span style="color: #339933;">::</span><span style="color: #006600;">HTTPClient</span>;     
...
<span style="color: #000000; font-weight: bold;">sub</span> start <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span>;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$t</span>; <span style="color: #0000ff;">$t</span> <span style="color: #339933;">=</span> AE<span style="color: #339933;">::</span><span style="color: #006600;">timer</span> 0<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1800</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">scalar</span> <span style="color: #0000ff;">$t</span>;
        <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch_feeds</span>;
    <span style="color: #009900;">&#125;</span>;
<span style="color: #009900;">&#125;</span>
....
<span style="color: #000000; font-weight: bold;">sub</span> fetch_feeds <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$url</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;
    Tatsumaki<span style="color: #339933;">::</span><span style="color: #006600;">HTTPClient</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">get</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$url</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">#do the fetch and parsing stuff });</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>From now, every 60 minutes, feeds will be checked. Tatsumaki::HTTPClient is a HTTP client based on AnyEvent::HTTP.</p>
<p>Let&#8217;s write the app now</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> Lifestream;            
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Moose;
extends <span style="color: #ff0000;">&quot;Tatsumaki::Application&quot;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Lifestream<span style="color: #339933;">::</span><span style="color: #006600;">Handler</span>;       
<span style="color: #000000; font-weight: bold;">use</span> Lifestream<span style="color: #339933;">::</span><span style="color: #006600;">Worker</span>;        
...
<span style="color: #000000; font-weight: bold;">sub</span> app <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$class</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">%args</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$class</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="">'/'</span> <span style="color: #339933;">=&gt;</span> <span style="">'Lifestream::Handler'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">config</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$args</span><span style="color: #009900;">&#123;</span>config<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span>; 
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_service</span><span style="color: #009900;">&#40;</span> Lifestream<span style="color: #339933;">::</span><span style="color: #006600;">Worker</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span> config <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">config</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>;
    <span style="color: #0000ff;">$self</span>;
<span style="color: #009900;">&#125;</span>
...
<span style="color: #000000; font-weight: bold;">sub</span> memes <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> services <span style="color: #009900;">&#123;</span>
....
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <strong>memes</strong> and <strong>services</strong> method called from the handler are defined here. In the app method, I &#8220;attch&#8221; the &#8220;/&#8221; path to the handler, and I add the service.</p>
<p>and to launch the app</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$app</span> <span style="color: #339933;">=</span> Lifestream<span style="color: #339933;">-&gt;</span><span style="color: #006600;">app</span><span style="color: #009900;">&#40;</span> config <span style="color: #339933;">=&gt;</span> LoadFile<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>;
<span style="color: #000066;">require</span> Tatsumaki<span style="color: #339933;">::</span><span style="color: #006600;">Server</span>;      
Tatsumaki<span style="color: #339933;">::</span><span style="color: #006600;">Server</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
    port <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">9999</span><span style="color: #339933;">,</span>
    host <span style="color: #339933;">=&gt;</span> 0<span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">run</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$app</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>And that&#8217;s it, I now have a nice webapp, with something like only 200 LOC. I will keep playing with <a href="http://www.slideshare.net/miyagawa/tatsumaki">Tatsumaki</a> as I have more ideas (and probably subfeedr too). Thanks to <a href="http://bulknews.typepad.com/">miyagawa</a> for all this code.</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/12/21/tatsumaki-or-how-to-write-a-nice-webapp-in-less-than-two-hours/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MooseX::Net::API</title>
		<link>http://lumberjaph.net/blog/index.php/2009/12/20/moosexnetapi/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/12/20/moosexnetapi/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 16:40:45 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[ironman]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[moose]]></category>

		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=551</guid>
		<description><![CDATA[Net::Twitter
I&#8217;ve been asked for $work to write an API client for backtype, as we plan to integrate it in one of our services. A couple of days before I was reading the Net::Twitter source code, and I&#8217;ve found interesting how semifor wrote it.
Basically, what Net::Twitter does is this: for each API method, there is a [...]]]></description>
			<content:encoded><![CDATA[<h2>Net::Twitter</h2>
<p>I&#8217;ve been asked for <a href="http://linkfluence.net">$work</a> to write an API client for <a href="http://www.backtype.com/">backtype</a>, as we plan to integrate it in one of our services. A couple of days before I was reading the <a href="http://search.cpan.org/perldoc?Net::Twitter">Net::Twitter</a> source code, and I&#8217;ve found interesting how <a href="http://blog.questright.com/">semifor</a> wrote it.</p>
<p>Basically, what Net::Twitter does is this: for each API method, there is a <strong>twitter_api_method</strong> method, where the only code for this method is an API specification of the method. Let&#8217;s look at the public timeline method:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;">twitter_api_method home_timeline <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
    description <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">&lt;&lt;</span><span style="">''</span><span style="color: #339933;">,</span>
Returns the <span style="color: #cc66cc;">20</span> most recent statuses<span style="color: #339933;">,</span> including retweets<span style="color: #339933;">,</span> posted by the
authenticating user <span style="color: #b1b100;">and</span> that user<span style="">'s friends. This is the equivalent of
/timeline/home on the Web.
&nbsp;
    path      =&gt; '</span>statuses<span style="color: #339933;">/</span>home_timeline<span style="">',
    method    =&gt; '</span>GET<span style="">',
    params    =&gt; [qw/since_id max_id count page/],
    required  =&gt; [],
    returns   =&gt; '</span>ArrayRef<span style="color: #009900;">&#91;</span>Status<span style="color: #009900;">&#93;</span><span style="">',
);</span></pre></div></div>

<p>The <strong>twitter_api_method</strong> method is exported with Moose::Exporter. It generates a sub called <strong>home_timeline</strong> that is added to the class.</p>
<h2>MooseX::Net::API</h2>
<p>As I&#8217;ve found this approch nice and simple, I thought about writing a <a href="http://github.com/franckcuny/moosex-net-api">little framework</a> to easily write API client this way. I will show how I&#8217;ve write a <a href="http://github.com/franckcuny/net-backtype">client for the Backtype API</a> using this (I&#8217;ve wrote some other client for private API at works too).</p>
<h3>Backtype API</h3>
<p>First we defined our class:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> Net<span style="color: #339933;">::</span><span style="color: #006600;">Backtweet</span>;        
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Moose;
<span style="color: #000000; font-weight: bold;">use</span> MooseX<span style="color: #339933;">::</span><span style="color: #006600;">Net</span><span style="color: #339933;">::</span><span style="color: #006600;">API</span>;</pre></div></div>

<p>MooseX::Net::API export two methods: <strong>net_api_declare</strong> and <strong>net_api_method</strong>. The first method is for all the paramters that are common for each method. For Backtype, I&#8217;ll get this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;">net_api_declare backtweet <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
    base_url    <span style="color: #339933;">=&gt;</span> <span style="">'http://backtweets.com'</span><span style="color: #339933;">,</span>
    <span style="color: #000066;">format</span>      <span style="color: #339933;">=&gt;</span> <span style="">'json'</span><span style="color: #339933;">,</span>
    format_mode <span style="color: #339933;">=&gt;</span> <span style="">'append'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>This set </p>
<ul>
<li>the base URL for the API</li>
<li>the format is JSON</li>
<li>some API use an extension at the name of the method to determine the format. &#8220;append&#8221; do this.</li>
</ul>
<p>Right now three formats are supported: xml json and yaml. Two modes are supported: <em>append</em> and <em>content-type</em>.</p>
<p>Now the <strong>net_api_method</strong> method.</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;">net_api_method backtweet_search <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
    path     <span style="color: #339933;">=&gt;</span> <span style="">'/search'</span><span style="color: #339933;">,</span>
    method   <span style="color: #339933;">=&gt;</span> <span style="">'GET'</span><span style="color: #339933;">,</span>
    params   <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #000066;">qw</span><span style="color: #339933;">/</span><span style="color: #000066;">q</span> since key<span style="color: #339933;">/</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>  
    required <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #000066;">qw</span><span style="color: #339933;">/</span><span style="color: #000066;">q</span> key<span style="color: #339933;">/</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    expected <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #000066;">qw</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">200</span><span style="color: #339933;">/</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span>;</pre></div></div>

<ul>
<li><strong>path</strong>: path for the method (required)</li>
<li><strong>method</strong>: how to acces this resource (GET POST PUT and DELETE are supported) (required)</li>
<li><strong>params</strong>: list of parameters to access this resource (required)</li>
<li><strong>required</strong>: which keys are required</li>
<li><strong>expected</strong>: list of HTTP code accepted</li>
</ul>
<p>To use it:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$backtype</span> <span style="color: #339933;">=</span> Net<span style="color: #339933;">::</span><span style="color: #006600;">Bactype</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$res</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$backtype</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">backtweet_search</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">q</span> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;http://lumberjaph.net&quot;</span><span style="color: #339933;">,</span> key <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;foo&quot;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #000066;">warn</span> Dump <span style="color: #0000ff;">$res</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>tweets<span style="color: #009900;">&#125;</span>;</pre></div></div>

<h3>MooseX::Net::API implementation</h3>
<p>Now, what is done by the framework. The <strong>net_api_declare</strong> method add various attributes to the class:</p>
<ul>
<li><strong>api_base_url</strong>: base URL of the API</li>
<li><strong>api_format</strong>: format for the query</li>
<li><strong>api_format_mode</strong>: how the format is used (append or content-type)</li>
<li><strong>api_authentication</strong>: if the API requires authentication</li>
<li><strong>api_username</strong>: the username for accessing the resource</li>
<li><strong>api_password</strong>: the password</li>
<li><strong>api_authentication</strong>: does the resource requires to be authenticated</li>
</ul>
<p>It will also apply two roles, for serialization and deserialization, unless you provides your own roles for this. You can provides your own method for useragent and authentication too (the module only do basic authentication).</p>
<p>For the <strong>net_api_method</strong> method, you can overload the authentication (in case some resources requires authentication).  You can also overload the default code generated.</p>
<p>In case there is an error, an MooseX::Net::API::Error will be throw.</p>
<h2>Conclusion</h2>
<p>Right now, this module is not finished. I&#8217;m looking for suggestions (what should be added, done better, how I can improve stuff, &#8230;). I&#8217;m not aiming to handle all possibles API, but at least most of the REST API avaible. I&#8217;ve uploaded a first version of <a href="http://search.cpan.org/perldoc?MooseX::Net::API">MooseX::Net::API</a> and <a href="http://search.cpan.org/perldoc?Net::Backtype">Net::Backtype</a> on CPAN, and <a href="http://github.com/franckcuny/net-backtype">the code</a> is <a href="http://github.com/franckcuny/moosex-net-api">available on github</a>.</p>
<p>For testing purpose, i&#8217;ve set a dumb REST service <a href="http://lumberjaph.net/demorest/rest/users/">here</a> (the code is <a href="http://github.com/franckcuny/demorest">here</a>). I will update this service to add more tests to MX::Net::API.</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/12/20/moosexnetapi/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Riak, Perl and KiokuDB</title>
		<link>http://lumberjaph.net/blog/index.php/2009/12/13/riak-perl-and-kiokudb/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/12/13/riak-perl-and-kiokudb/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 20:33:26 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[apps]]></category>

		<category><![CDATA[ironman]]></category>

		<category><![CDATA[anyevent]]></category>

		<category><![CDATA[kiokudb]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[riak]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=509</guid>
		<description><![CDATA[As I was looking for a system to store documents at $work, Riak was pointed to me by one of my coworkers. I&#8217;m looking for a solution of this type to store various types of documents, from HTML pages to json. I need a system that is distributed, faul tolerant, and that works with Perl.
So [...]]]></description>
			<content:encoded><![CDATA[<p>As I was looking for a system to store documents at <a href="http://linkfluence.net">$work</a>, <a href="http://www.basho.com/Riak.html">Riak</a> was pointed to me by one of my coworkers. I&#8217;m looking for a solution of this type to store various types of documents, from HTML pages to json. I need a system that is distributed, faul tolerant, and that works with Perl.</p>
<p>So Riak is a document based database, it&#8217;s key value, no sql, REST, and in Erlang. You can read more about it <a href="http://riak.basho.com/nyc-nosql/">here</a> or watch an introduction <a href="http://vimeo.com/6973519">here</a>. Like <ahref="http://couchdb.apache.org/">CouchDB</a>, Riak provides a REST interface, so you don&#8217;t have to write any Erlang code.</p>
<p>One of the nice things with Riak it&#8217;s that it let you defined the N, R and W value for each operation. This values are:</p>
<ul>
<li>N: the number of replicas of each value to store</li>
<li>R: the number of replicas required to perform a read operation</li>
<li>W: the number of replicas needed for a write operation</li>
</ul>
<p>Riak comes with library for python ruby PHP and even javascript, but not for Perl. As all these libraries are just communicating with Riak via the REST interface, I&#8217;ve <a href="http://github.com/franckcuny/anyevent-riak">started to write one</a> using AnyEvent::HTTP, and <a href="http://github.com/franckcuny/kiokudb-backend-riak">also a backend for KiokuDB</a>.</p>
<h3>Installing and using Riak</h3>
<p>If you interested in Riak, you can install it easily. First, you will need the Erlang VM. On debian, a simple</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">aptitude</span> <span style="color: #c20cb9; font-weight: bold;">install</span> erlang</pre></div></div>

<p>install everything you need. Next step is to install Riak:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>hg.basho.com<span style="color: #000000; font-weight: bold;">/</span>riak<span style="color: #000000; font-weight: bold;">/</span>get<span style="color: #000000; font-weight: bold;">/</span>riak-0.6.2.tar.gz
<span style="color: #c20cb9; font-weight: bold;">tar</span> xzf riak-0.6.2.tar.gz
<span style="color: #7a0874; font-weight: bold;">cd</span> riak
<span style="color: #c20cb9; font-weight: bold;">make</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">RIAK</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">pwd</span><span style="color: #000000; font-weight: bold;">`</span></pre></div></div>

<p>Now, you can start to use it with</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>start-fresh config<span style="color: #000000; font-weight: bold;">/</span>riak-demo.erlenv</pre></div></div>

<p>or if you want to test it in cluster mode, you can write a configuration like this:</p>
<pre>
{cluster_name, "default"}.
{ring_state_dir, "priv/ringstate"}.
{ring_creation_size, 16}.
{gossip_interval, 60000}.
{storage_backend, riak_fs_backend}.
{riak_fs_backend_root, "/opt/data/riak/"}.
{riak_cookie, riak_demo_cookie}.
{riak_heart_command, "(cd $RIAK; ./start-restart.sh $RIAK/config/riak-demo.erlenv)"}.
{riak_nodename, riakdemo}.
{riak_hostname, "192.168.0.11"}.
{riak_web_ip, "192.168.0.11"}.
{riak_web_port, 8098}.
{jiak_name, "jiak"}.
{riak_web_logdir, "/tmp/riak_log"}.
</pre>
<p>Copy this config on a second server, edit it to replace the riak_hostname and riak_nodename. On the first server, start it like show previously, then on the second, with</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>start-join.sh config<span style="color: #000000; font-weight: bold;">/</span>riak-demo.erlenv 192.168.0.11</pre></div></div>

<p>where the IP address it the address of the first node in your cluster.</p>
<p>Let&#8217;s check if everything works:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">curl <span style="color: #660033;">-X</span> PUT <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Content-type: application/json&quot;</span> \
    http:<span style="color: #000000; font-weight: bold;">//</span>192.168.0.11:<span style="color: #000000;">8098</span><span style="color: #000000; font-weight: bold;">/</span>jiak<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>lumberjaph<span style="color: #000000; font-weight: bold;">/</span> \
    <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;{<span style="color: #000099; font-weight: bold;">\&quot;</span>bucket<span style="color: #000099; font-weight: bold;">\&quot;</span>:<span style="color: #000099; font-weight: bold;">\&quot;</span>blog<span style="color: #000099; font-weight: bold;">\&quot;</span>,<span style="color: #000099; font-weight: bold;">\&quot;</span>key<span style="color: #000099; font-weight: bold;">\&quot;</span>:<span style="color: #000099; font-weight: bold;">\&quot;</span>lumberjaph<span style="color: #000099; font-weight: bold;">\&quot;</span>,<span style="color: #000099; font-weight: bold;">\&quot;</span>object<span style="color: #000099; font-weight: bold;">\&quot;</span>:{<span style="color: #000099; font-weight: bold;">\&quot;</span>title<span style="color: #000099; font-weight: bold;">\&quot;</span>:<span style="color: #000099; font-weight: bold;">\&quot;</span>I'm a lumberjaph, and I'm ok<span style="color: #000099; font-weight: bold;">\&quot;</span>},<span style="color: #000099; font-weight: bold;">\&quot;</span>links<span style="color: #000099; font-weight: bold;">\&quot;</span>:[]}&quot;</span>
&nbsp;
curl <span style="color: #660033;">-i</span> http:<span style="color: #000000; font-weight: bold;">//</span>192.168.0.11:<span style="color: #000000;">8098</span><span style="color: #000000; font-weight: bold;">/</span>jiak<span style="color: #000000; font-weight: bold;">/</span>blog<span style="color: #000000; font-weight: bold;">/</span>lumberjaph<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>will output (with the HTTP blabla)</p>

<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;object&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;title&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;I'm a lumberjaph, and I'm ok&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;vclock&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;a85hYGBgzGDKBVIsbGubKzKYEhnzWBlCTs08wpcFAA==&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;lastmod&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;Sun, 13 Dec 2009 20:28:04 GMT&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;vtag&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;5YSzQ7sEdI3lABkEUFcgXy&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;bucket&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;blog&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;key&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;lumberjaph&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;links&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Using Riak with Perl and KiokuDB</h3>
<p>I need to store various things in Riak: html pages, json data, and objects using KiokuDB. I&#8217;ve started to write a client for Riak with AnyEvent, so I can do simple operations at the moment, (listing information about a bucket, defining a new bucket with a specific schema, storing, retriving and deleting documents). To create a client, you need to</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$client</span> <span style="color: #339933;">=</span> AnyEvent<span style="color: #339933;">::</span><span style="color: #006600;">Riak</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
    host <span style="color: #339933;">=&gt;</span> <span style="">'http://127.0.0.1:8098'</span><span style="color: #339933;">,</span>
    path <span style="color: #339933;">=&gt;</span> <span style="">'jiak'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>As Riak exposes to you it&#8217;s N, R, and W value, you can also set them in creation the client:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$client</span> <span style="color: #339933;">=</span> AnyEvent<span style="color: #339933;">::</span><span style="color: #006600;">Riak</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
    host <span style="color: #339933;">=&gt;</span> <span style="">'http://127.0.0.1:8098'</span><span style="color: #339933;">,</span>
    path <span style="color: #339933;">=&gt;</span> <span style="">'jiak'</span><span style="color: #339933;">,</span>            
    r    <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span>
    w    <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span>                 
    dw   <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>where:</p>
<ul>
<li>the W and DW values define that the request returns as soon as at least W nodes have received the request, and at least DW nodes have stored it in their storage backend. </li>
<li>with the R value, the request returns as soon as R nodes have responded with a value or an error. You can also set this values when calling fetch, store and delete. By default, the value is set to 2.</li>
</ul>
<p>So, if you wan to store a value, retrieve it, then delete it, you can do:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$store</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">store</span><span style="color: #009900;">&#40;</span>                                           
    <span style="color: #009900;">&#123;</span> bucket <span style="color: #339933;">=&gt;</span> <span style="">'foo'</span><span style="color: #339933;">,</span> key <span style="color: #339933;">=&gt;</span> <span style="">'bar'</span><span style="color: #339933;">,</span> object <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> baz <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">recv</span>;    
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$fetch</span>  <span style="color: #339933;">=</span> <span style="color: #0000ff;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #009900;">&#40;</span> <span style="">'foo'</span><span style="color: #339933;">,</span> <span style="">'bar'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">recv</span>;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$delete</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">delete</span><span style="color: #009900;">&#40;</span> <span style="">'foo'</span><span style="color: #339933;">,</span> <span style="">'bar'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">recv</span>;</pre></div></div>

<p>If there is an error, the croak method from AnyEvent is used, so you may prefer to do this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> Try<span style="color: #339933;">::</span><span style="color: #006600;">Tiny</span>;
try <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$fetch</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #009900;">&#40;</span><span style="">'foo'</span><span style="color: #339933;">,</span> <span style="">'baz'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">recv</span>;
<span style="color: #009900;">&#125;</span>catch<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$err</span> <span style="color: #339933;">=</span> decode_json <span style="color: #0000ff;">$_</span>;
  say <span style="color: #ff0000;">&quot;error: code =&gt; &quot;</span>.<span style="color: #0000ff;">$err</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span>.<span style="color: #ff0000;">&quot; reason =&gt; &quot;</span>.<span style="color: #0000ff;">$err</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>;
<span style="color: #009900;">&#125;</span>;</pre></div></div>

<p>The error contains an array, with the first value the HTTP code, and the second value the reason of the error given by Riak.</p>
<p>At the moment, the KiokuDB backend is not complete, but if you want to start to play with is, all you need to do is:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dir</span> <span style="color: #339933;">=</span> KiokuDB<span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
    backend <span style="color: #339933;">=&gt;</span> KiokuDB<span style="color: #339933;">::</span><span style="color: #006600;">Backend</span><span style="color: #339933;">::</span><span style="color: #006600;">Riak</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
        db <span style="color: #339933;">=&gt;</span> AnyEvent<span style="color: #339933;">::</span><span style="color: #006600;">Riak</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>      
            host <span style="color: #339933;">=&gt;</span> <span style="">'http://localhost:8098'</span><span style="color: #339933;">,</span>
            path <span style="color: #339933;">=&gt;</span> <span style="">'jiak'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        bucket <span style="color: #339933;">=&gt;</span> <span style="">'kiokudb'</span><span style="color: #339933;">,</span>            
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span>;
&nbsp;
<span style="color: #0000ff;">$dir</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">txn_do</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$dir</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$object</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/12/13/riak-perl-and-kiokudb/feed/</wfw:commentRss>
		</item>
		<item>
		<title>sd : the peer to peer bug tracking system</title>
		<link>http://lumberjaph.net/blog/index.php/2009/11/17/sd-the-peer-to-peer-bug-tracking-system/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/11/17/sd-the-peer-to-peer-bug-tracking-system/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 20:03:28 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[apps]]></category>

		<category><![CDATA[ironman]]></category>

		<category><![CDATA[bugtracking]]></category>

		<category><![CDATA[git]]></category>

		<category><![CDATA[perl]]></category>

		<category><![CDATA[sd]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=488</guid>
		<description><![CDATA[SD is a peer to peer bug tracking system build on top of Prophet. Prophet is  A grounded, semirelational, peer to peer replicated, disconnected, versioned, property database with self-healing conflict resolution. SD can be used alone, on an existing bug tracking system (like RT or redmine or github) and it plays nice with git.
Why [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://syncwith.us/sd/">SD</a> is a peer to peer bug tracking system build on top of <a href="http://syncwith.us/">Prophet</a>. Prophet is <strong> A grounded, semirelational, peer to peer replicated, disconnected, versioned, property database with self-healing conflict resolution</strong>. SD can be used alone, on an existing bug tracking system (like RT or redmine or github) and it plays nice with git.</p>
<p>Why should you use SD ? Well, at <a href="http://linkfluence.net/">$work</a> we are using <a href="http://www.redmine.org/">redmine</a> as our ticket tracker.  I spend a good part of my time in a terminal, and checking the ticket system, adding a ticket, etc, using the browser, is annoying. I prefer something which I can use in my terminal and edit with my <a href="http://www.vim.org/">$EDITOR</a>. So if you recognize yourself in this description, you might want to take a look at SD.</p>
<blockquote><p>
In the contrib directory of the SD distribution, you will find a SD ticket syntax file for vim.
</p></blockquote>
<h3>how to do some basic stuff with sd</h3>
<p>We will start by initializing a database. By default</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">sd init</pre></div></div>

<p>will create a <strong>.sd</strong> directory in your $HOME. If you want to create in a specific path, you will need to set the SD_REPO in your env.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd sd init</pre></div></div>

<p>The init command creates an sqlite database and a config file. The config file is in the same format as the one used by git.</p>
<p>Now we can create a ticket:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd ticket create</pre></div></div>

<p>This will open your $EDITOR, the part you need to edit are specified. After editing this file, you will get something like this:</p>
<blockquote><p>
Created ticket 11 (437b823c-8f69-46ff-864f-a5f74964a73f)<br />
Created comment 12 (f7f9ee13-76df-49fe-b8b2-9b94f8c37989)
</p></blockquote>
<p>You can view the created ticket:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd ticket show <span style="color: #000000;">11</span></pre></div></div>

<p>and the content of your ticket will be displayed.</p>
<p>You can list and filter your tickets:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd ticket list
<span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd search <span style="color: #660033;">--regex</span> foo</pre></div></div>

<p>You can edit the SD configuration using the config tool or editing directly the file. SD will look for three files : /etc/sdrc, $HOME/.sdrc or the config file in your replica (in our exemple, ~/code/myproject/sd/config).</p>
<p>For changing my email address, I can do it this way:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd config user.email-address franck<span style="color: #000000; font-weight: bold;">@</span>lumberjaph.net</pre></div></div>

<p>or directly</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #007800;">SD_REPO</span>=~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>myproject<span style="color: #000000; font-weight: bold;">/</span>sd config edit</pre></div></div>

<p>and update the user section.</p>
<h3>sd with git</h3>
<p>SD provides a script for git: <strong>git-sd</strong>.</p>
<p>Let&#8217;s start by creating a git repository:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> ~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>git<span style="color: #000000; font-weight: bold;">/</span>myuberproject
<span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>code<span style="color: #000000; font-weight: bold;">/</span>git<span style="color: #000000; font-weight: bold;">/</span>myuberproject
git init</pre></div></div>

<p>SD comes with a git hook named &#8220;git-post-commit-close-ticket&#8221; (in the contrib directory). We will copy this script to <strong>.git/hooks/post-commit</strong>.</p>
<p>now we can initialize our sd database</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git-sd init</pre></div></div>

<p>git-sd will try to find which email you have choosen for this project using git config, and use the same address for it&#8217;s configuration.</p>
<p>Let&#8217;s write some code for our new project</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/env perl</span>
<span style="color: #000000; font-weight: bold;">use</span> strict;
<span style="color: #000000; font-weight: bold;">use</span> warnings;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;hello, world<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git add hello.pl
git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;first commit&quot;</span> hello.pl</pre></div></div>

<p>now we can create a new entry</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git-sd ticket create <span style="color: #666666; font-style: italic;"># create a ticket to replace print with say</span></pre></div></div>

<p>We note the UUID for the ticket: in my exemple, the following output is produced:</p>
<blockquote><p>
Created ticket 11 (92878841-d764-4ac9-8aae-cd49e84c1ffe)<br />
Created comment 12 (ddb1e56e-87cb-4054-a035-253be4bc5855)
</p></blockquote>
<p>so my UUID is <strong>92878841-d764-4ac9-8aae-cd49e84c1ffe</strong>.</p>
<p>Now, I fix my bug</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/env perl</span>
<span style="color: #000000; font-weight: bold;">use</span> strict;
<span style="color: #000000; font-weight: bold;">use</span> <span style="color: #cc66cc;">5.010</span>;
<span style="color: #000000; font-weight: bold;">use</span> warnings;
say <span style="color: #ff0000;">&quot;hello, world&quot;</span>;</pre></div></div>

<p>and commit it</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Closes 92878841-d764-4ac9-8aae-cd49e84c1ffe&quot;</span> hello.pl</pre></div></div>

<p>If I do a</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git ticket show <span style="color: #000000;">92878841</span>-d764-4ac9-8aae-cd49e84c1ffe</pre></div></div>

<p>The ticket will be marked as closed.</p>
<h3>sd with github</h3>
<p>Let&#8217;s say you want to track issues from a project (I will use <a href="http://plackperl.org/">Plack</a> for this exemple) that is hosted on github.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git clone git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>miyagawa<span style="color: #000000; font-weight: bold;">/</span>Plack.git
git-sd clone <span style="color: #660033;">--from</span> <span style="color: #ff0000;">&quot;github:http://github.com/miyagawa/Plack&quot;</span>
<span style="color: #666666; font-style: italic;"># it's the same as</span>
git-sd clone <span style="color: #660033;">--from</span> <span style="color: #ff0000;">&quot;github:miyagawa/Plack&quot;</span>
<span style="color: #666666; font-style: italic;"># or if you don't want to be prompted for username and password each time</span>
 git-sd clone <span style="color: #660033;">--from</span> github:http:<span style="color: #000000; font-weight: bold;">//</span>githubusername:apitoken<span style="color: #000000; font-weight: bold;">@</span>github.com<span style="color: #000000; font-weight: bold;">/</span>miyagawa<span style="color: #000000; font-weight: bold;">/</span>Plack.git</pre></div></div>

<p>It will ask for you github username and your API token, and clone the database.</p>
<p>Later, you can publish your sd database like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">git-sd push <span style="color: #660033;">--to</span> <span style="color: #ff0000;">&quot;github:http://github.com/$user/$project&quot;</span></pre></div></div>

<p>Now you can code offline with git, and open/close tickets using SD :)</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/11/17/sd-the-peer-to-peer-bug-tracking-system/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Modules I like : Devel::Declare</title>
		<link>http://lumberjaph.net/blog/index.php/2009/11/09/modules-i-like-develdeclare/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/11/09/modules-i-like-develdeclare/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 09:27:57 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[ironman]]></category>

		<category><![CDATA[Devel::Declare]]></category>

		<category><![CDATA[moose]]></category>

		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=477</guid>
		<description><![CDATA[For $work, I&#8217;ve been working on a job queue system, using Moose, Catalyst (for a REST API) and DBIx::Class to store the jobs and some meta (yeah I know, there is not enough job queue system already, the world really needs a new one &#8230;).
Basicaly, I&#8217;ve got a XXX::Worker class that all the workers extends. [...]]]></description>
			<content:encoded><![CDATA[<p>For <a href="http://linkfluence.net/">$work</a>, I&#8217;ve been working on a job queue system, using Moose, Catalyst (for a REST API) and DBIx::Class to store the jobs and some meta (yeah I know, there is not enough job queue system already, the world really needs a new one &#8230;).</p>
<p>Basicaly, I&#8217;ve got a XXX::Worker class that all the workers extends. This class provide methods for fetching job, add a new job, mark a job as fail, retry, &#8230; </p>
<p>The main loop in the XXX::Worker class look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># $context is a hashref with some info the job or method may need</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@jobs</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch_jobs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #b1b100;">foreach</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$job</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@jobs</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>funcname<span style="color: #009900;">&#125;</span>;
        <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #0000ff;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$context</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$job</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">wait</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>and the worker look like this</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> MyWorker;
<span style="color: #000000; font-weight: bold;">use</span> Moose;
extends <span style="">'XXX::Worker'</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> foo <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$context</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$job</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;
    <span style="color: #666666; font-style: italic;"># do something</span>
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">job_success</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>But as I&#8217;m using Moose, I want to add more sugar to the syntax, so writing a new worker would be really more easy.</p>
<p>Here comes <a href="http://search.cpan.org/~flora/Devel-Declare-0.005011/lib/Devel/Declare.pm">Devel::Declare</a>.</p>
<p>The syntax I want for my worker is this one:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;">work foo <span style="color: #009900;">&#123;</span>
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">logger</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">info</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;start to work on job&quot;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #666666; font-style: italic;"># do something with $job</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
work bar <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;"># do something with $job</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
success foo <span style="color: #009900;">&#123;</span>
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">logger</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">info</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;woot job success&quot;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
fail bar <span style="color: #009900;">&#123;</span>
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">logger</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">info</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;ho noez this one failed&quot;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Where with &#8216;<strong>work</strong>&#8216; I write the code the writer will execute on a task, &#8216;<strong>success</strong>&#8216;, a specific code that will be executed after a job is marked as successfull, and &#8216;<strong>fail</strong>&#8216; for when the job fail.</p>
<p>I will show how to add the &#8216;<strong>work</strong>&#8216; keyword. I start by writing a new package :</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;">XXX<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span><span style="color: #339933;">:</span>
&nbsp;
<span style="color: #000066;">package</span> XXX<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Moose;
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">::</span><span style="color: #006600;">Exporter</span>;
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">::</span><span style="color: #006600;">Util</span><span style="color: #339933;">::</span><span style="color: #006600;">MetaRole</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Devel<span style="color: #339933;">::</span><span style="color: #006600;">Declare</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> XXX<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span><span style="color: #339933;">::</span><span style="color: #006600;">Class</span>;
<span style="color: #000000; font-weight: bold;">use</span> XXX<span style="color: #339933;">::</span><span style="color: #006600;">Keyword</span><span style="color: #339933;">::</span><span style="color: #006600;">Work</span>;
&nbsp;
Moose<span style="color: #339933;">::</span><span style="color: #006600;">Exporter</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">setup_import_methods</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> init_meta <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$me</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">%options</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$for</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$options</span><span style="color: #009900;">&#123;</span>for_class<span style="color: #009900;">&#125;</span>;
&nbsp;
    XXX<span style="color: #339933;">::</span><span style="color: #006600;">Keyword</span><span style="color: #339933;">::</span><span style="color: #006600;">Work</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">install_methodhandler</span><span style="color: #009900;">&#40;</span> into <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$for</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#41;</span>;
&nbsp;
    Moose<span style="color: #339933;">::</span><span style="color: #006600;">Util</span><span style="color: #339933;">::</span><span style="color: #006600;">MetaRole</span><span style="color: #339933;">::</span><span style="color: #006600;">apply_metaclass_roles</span><span style="color: #009900;">&#40;</span>
        for_class       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$for</span><span style="color: #339933;">,</span>
        metaclass_roles <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="">'XXX::Meta::Class'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span>;
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span>;</pre></div></div>

<p>The <strong>init_meta</strong> method is provided by Moose: (from the POD)</p>
<blockquote><p>The <strong>init_meta</strong> method sets up the metaclass object for the class specified by <strong>for_class</strong>. This method injects a a meta accessor into the class so you can get at this object. It also sets the class&#8217;s superclass to base_class, with Moose::Object as the default.</p></blockquote>
<p>So I inject into the class that will use XXX::Meta a new metaclass, XXX::Meta::Class.</p>
<p>Let&#8217;s take a look to XXX::Meta::Class:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> XXX<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span><span style="color: #339933;">::</span><span style="color: #006600;">Class</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">::</span><span style="color: #006600;">Role</span>;
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span><span style="color: #339933;">::</span><span style="color: #006600;">Class</span>;
<span style="color: #000000; font-weight: bold;">use</span> MooseX<span style="color: #339933;">::</span><span style="color: #006600;">Types</span><span style="color: #339933;">::</span><span style="color: #006600;">Moose</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>Str ArrayRef ClassName Object<span style="color: #009900;">&#41;</span>;
&nbsp;
has work_metaclass  <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
    is      <span style="color: #339933;">=&gt;</span> <span style="">'ro'</span><span style="color: #339933;">,</span>
    isa     <span style="color: #339933;">=&gt;</span> Object<span style="color: #339933;">,</span>
    builder <span style="color: #339933;">=&gt;</span> <span style="">'_build_metaclass'</span><span style="color: #339933;">,</span>
    lazy    <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span>;
&nbsp;
has <span style="">'local_work'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span>
    traits     <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="">'Array'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    is         <span style="color: #339933;">=&gt;</span> <span style="">'ro'</span><span style="color: #339933;">,</span>
    isa        <span style="color: #339933;">=&gt;</span> ArrayRef <span style="color: #009900;">&#91;</span>Str<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    required   <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    default    <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    auto_deref <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    handles    <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> <span style="">'_add_work'</span> <span style="color: #339933;">=&gt;</span> <span style="">'push'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#41;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> _build_metaclass <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span>;
    <span style="color: #000066;">return</span> Moose<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span><span style="color: #339933;">::</span><span style="color: #006600;">Class</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">create_anon_class</span><span style="color: #009900;">&#40;</span>
        superclasses <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">method_metaclass</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        cache        <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> add_local_method <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$method</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$code</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$method_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$method</span> . <span style="color: #ff0000;">&quot;_&quot;</span> . <span style="color: #0000ff;">$name</span>;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$body</span>        <span style="color: #339933;">=</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">work_metaclass</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">name</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">wrap</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">$code</span><span style="color: #339933;">,</span>
        original_body <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$code</span><span style="color: #339933;">,</span>
        name          <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$method_name</span><span style="color: #339933;">,</span>
        package_name  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">name</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span>;
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$method_add</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;_add_&quot;</span> . <span style="color: #0000ff;">$method</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_method</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$method_name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$body</span> <span style="color: #009900;">&#41;</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #0000ff;">$method_add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$method_name</span><span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span>;</pre></div></div>

<p>Here I add to the <strong>->meta</strong> provided by Moose &#8216;<strong>local_work</strong>&#8216;, which is an array that contains all my &#8216;<strong>work</strong>&#8216; methods. So each time I do something like</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;">work foo <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
work bar <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>in my worker, I add this method to <strong>->meta->local_work</strong>.</p>
<p>And the class for our keyword work:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> XXX<span style="color: #339933;">::</span><span style="color: #006600;">Keyword</span><span style="color: #339933;">::</span><span style="color: #006600;">Work</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict;
<span style="color: #000000; font-weight: bold;">use</span> warnings;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Devel<span style="color: #339933;">::</span><span style="color: #006600;">Declare</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">use</span> Sub<span style="color: #339933;">::</span><span style="color: #006600;">Name</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> base <span style="">'Devel::Declare::Context::Simple'</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> install_methodhandler <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$class</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span>;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%args</span>  <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">no</span> strict <span style="">'refs'</span>;
        <span style="color: #339933;">*</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$args</span><span style="color: #009900;">&#123;</span>into<span style="color: #009900;">&#125;</span> . <span style="">'::work'</span> <span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$ctx</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$class</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%args</span><span style="color: #009900;">&#41;</span>;
    Devel<span style="color: #339933;">::</span><span style="color: #006600;">Declare</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">setup_for</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">$args</span><span style="color: #009900;">&#123;</span>into<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span>
            work <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
                const <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$ctx</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">parser</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@_</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> parser <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">init</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@_</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">skip_declarator</span>;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">strip_name</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">strip_proto</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">strip_attrs</span>;
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$inject</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">scope_injector_call</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">inject_if_block</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">$inject</span> . <span style="color: #ff0000;">&quot; my (<span style="color: #000099; font-weight: bold;">\$</span>self, <span style="color: #000099; font-weight: bold;">\$</span>content, <span style="color: #000099; font-weight: bold;">\$</span>job) = <span style="color: #000099; font-weight: bold;">\@</span>_; &quot;</span> <span style="color: #009900;">&#41;</span>;
&nbsp;
    <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$pack</span> <span style="color: #339933;">=</span> Devel<span style="color: #339933;">::</span><span style="color: #006600;">Declare</span><span style="color: #339933;">::</span><span style="color: #006600;">get_curstash_name</span>;
    Devel<span style="color: #339933;">::</span><span style="color: #006600;">Declare</span><span style="color: #339933;">::</span><span style="color: #006600;">shadow_sub</span><span style="color: #009900;">&#40;</span>
        <span style="color: #ff0000;">&quot;${pack}::work&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$work_method</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span>;
            <span style="color: #0000ff;">$pack</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">meta</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_local_method</span><span style="color: #009900;">&#40;</span> <span style="">'work'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$work_method</span> <span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#41;</span>;
    <span style="color: #000066;">return</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span>;</pre></div></div>

<p>The <strong>install_methodhandler</strong> add the <strong>work</strong> keyword, with a block of code. This code is sent to the parser, that will add more sugar. With the inject_if_block, I inject the following line</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$context</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$job</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span>;</pre></div></div>

<p>as this will always be my 3 arguments for a work method.</p>
<p>Now, for each new worker, I write something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl perl" style="font-family:monospace;"><span style="color: #000066;">package</span> MyWorker;
<span style="color: #000000; font-weight: bold;">use</span> Moose;
extends <span style="">'XXX::Worker'</span>;
<span style="color: #000000; font-weight: bold;">use</span> XXX<span style="color: #339933;">::</span><span style="color: #006600;">Meta</span>;
&nbsp;
work foo <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The next step is too find the best way to reduce the first four lines to two.</p>
<p>(some of this code is ripped from other modules that use Devel::Declare. The best way to learn what you can do with this module is to read code from other modules that use it)</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/11/09/modules-i-like-develdeclare/feed/</wfw:commentRss>
		</item>
		<item>
		<title>teh batmoose at osdc.fr</title>
		<link>http://lumberjaph.net/blog/index.php/2009/10/03/teh-batmoose-at-osdcfr/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/10/03/teh-batmoose-at-osdcfr/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 10:16:45 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[conference]]></category>

		<category><![CDATA[ironman]]></category>

		<category><![CDATA[batmoose]]></category>

		<category><![CDATA[moose]]></category>

		<category><![CDATA[osdc]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=468</guid>
		<description><![CDATA[Today I presented a talk about Moose at OSDC.fr. The slides are available here.
And big thanks to my friend Morgan for his illustration of the batmoose :)

]]></description>
			<content:encoded><![CDATA[<p>Today I presented a talk about Moose at <a href="http://osdc.fr/">OSDC.fr</a>. The slides are available <a href="http://lumberjaph.net/~franck/stuff/Introduction_a_Moose.pdf">here</a>.<br />
And big thanks to my friend <a href="http://www.bwoup.com/">Morgan</a> for his illustration of the batmoose :)<br />
<a href="http://bwoup.com/wp/index.php/illustration/batmoose/"><img src="http://lumberjaph.net/blog/wp-content/uploads/2009/10/batmoose_1024cut-300x225.png" alt="batmoose_1024cut" title="batmoose_1024cut" width="300" height="225" class="aligncenter size-medium wp-image-470" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/10/03/teh-batmoose-at-osdcfr/feed/</wfw:commentRss>
		</item>
		<item>
		<title>OSDC.fr</title>
		<link>http://lumberjaph.net/blog/index.php/2009/08/31/osdcfr/</link>
		<comments>http://lumberjaph.net/blog/index.php/2009/08/31/osdcfr/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 20:54:25 +0000</pubDate>
		<dc:creator>franck</dc:creator>
		
		<category><![CDATA[ironman]]></category>

		<category><![CDATA[conference]]></category>

		<category><![CDATA[osdc]]></category>

		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://lumberjaph.net/blog/?p=465</guid>
		<description><![CDATA[The 2nd and 3rd of October, will be held in Paris the Open Source Developers Conference. The purpose of this conference is to gather developers from various open source communities (Perl, Ruby, Python, &#8230;) during two days.
It&#8217;s still possible de submit a talk about the subject of your choice, and it&#8217;s important to note that [...]]]></description>
			<content:encoded><![CDATA[<p>The 2nd and 3rd of October, will be held in Paris the <a href="http://act.osdc.fr/osdc2009fr/index.html">Open Source Developers Conference</a>. The purpose of this conference is to gather developers from various open source communities (Perl, Ruby, Python, &#8230;) during two days.</p>
<p>It&#8217;s still possible de submit a talk about the subject of your choice, and it&#8217;s important to note that this conference is free.</p>
<p><a href="http://rtgi.fr">RTGI</a> is proud to be one of the sponsor of this event :).</p>
]]></content:encoded>
			<wfw:commentRss>http://lumberjaph.net/blog/index.php/2009/08/31/osdcfr/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
