<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Marco Fontani</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/marco_fontani/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/marco_fontani//56</id>
    <updated>2011-04-30T10:19:17Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>Dancing on a cloud made of pearls </title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2011/04/dancing-on-a-cloud-made-of-pearls.html" />
    <id>tag:blogs.perl.org,2011:/users/marco_fontani//56.1714</id>

    <published>2011-04-30T09:52:51Z</published>
    <updated>2011-04-30T10:19:17Z</updated>

    <summary>Thanks to a post on Hacker News, I got access to the beta test for DotCloud. In this blog post, I show how I got started and successfully deployed a small Perl Dancer web app to the service. I was...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="cloud" label="cloud" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="dancer" label="dancer" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="dotcloud" label="dotcloud" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>Thanks to a post on <a href="http://news.ycombinator.com/news">Hacker News</a>, I got access to the beta test for <a href="http://www.dotcloud.com/">DotCloud</a>.
In this blog post, I show how I got started and successfully deployed a small <a href="http://www.perl.org/">Perl</a> <a href="http://perldancer.org/">Dancer</a> web app to the service.</p>

<p>I was extremely pleased with how easy it was to do the above, and wanted to share it!</p>
]]>
        <![CDATA[<p>After creating the account on <a href="http://www.dotcloud.com/">DotCloud</a>, a quick and painless
endeavour, I followed along their <a href="http://docs.dotcloud.com/tutorials/firststeps/">first steps tutorial</a>, making
sure I&#8217;d change the various steps in order to deploy a <a href="http://www.perl.org/">Perl</a>
<a href="http://perldancer.org/">Dancer</a> webapp.</p>

<p>Here is the transcript of the first steps of the tutorial, which did not change for me:</p>

<pre><code>$ sudo aptitude install python-setuptools
[...]

$ sudo easy_install dotcloud
[...]

$ dotcloud
Warning: /home/okram/.dotcloud/dotcloud.conf does not exist.
Enter your api key (You can find it at http://www.dotcloud.com/account/settings): XXXXXXXXXXXXXXXXXXXXXXXXX
error: usage: dotcloud [-h]
    {status,info,run,logs,deploy,setup,list,alias,ssh,destroy,push,rollback,create,restart}
    ...
</code></pre>

<p>At this point I just went to the linked URL, and copy/pasted my API key.
Nothing strange so far.</p>

<p>I then created a new namespace, &#8220;weasel&#8221;, and an endpoint &#8220;www&#8221;.
Lastly, I checked it was created:</p>

<pre><code>$ dotcloud deploy -t perl weasel.www
Created "weasel.www".

$ dotcloud info weasel.www
cluster: wolverine
config: {}
created_at: 1304117136.2035949
name: weasel.www
namespace: weasel
state: booting
type: perl
</code></pre>

<p>Time for code! I created a new Git repo, and edited some files.
The full listing (heh!) will be at the end of the article.</p>

<pre><code>$ mkdir -p GIT/weasel/www
$ cd !$
$ git init
Initialized empty Git repository in /home/okram/GIT/weasel/www/.git/
$ vi -p myapp.pl Makefile.PL app.psgi
3 files to edit
$ git add * ; git commit -am "Initial commit"
[...]
</code></pre>

<p>The Makefile.PL contained <code>Dancer</code> as a prerequisite, as the <code>myapp.pl</code>
did not make use of any other Perl module.</p>

<p>It came the time to try deploying the webapp to dotcloud; easy!
Dotcloud took care of installing the <code>Dancer</code> prerequisite, along with
all the dependencies, and then tried to start the app.</p>

<pre><code>$ dotcloud push weasel.www .
# upload . ssh://dotcloud@uploader.dotcloud.com:1060/weasel.www
# git
Warning: Permanently added '[uploader.dotcloud.com]:1060,[174.129.15.77]:1060' (RSA) to the list of known hosts.
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 533 bytes, done.
Total 5 (delta 0), reused 0 (delta 0)
To ssh://dotcloud@uploader.dotcloud.com:1060/weasel.www
* [new branch]      master -&gt; master
Scheduling build
Fetching logs...
Warning: Permanently added '[www.weasel.dotcloud.com]:3254,[174.129.17.131]:3254' (RSA) to the list of known hosts.
-- Build started...
Makefile.PL
app.psgi
myapp.pl
Fetched code revision e4d8d81
--&gt; Working on .
Configuring /home/dotcloud/e4d8d81 ... OK
==&gt; Found dependencies: Dancer
--&gt; Working on Dancer
Fetching http://search.cpan.org/CPAN/authors/id/X/XS/XSAWYERX/Dancer-1.3030.tar.gz ... OK
Configuring Dancer-1.3030 ... OK
==&gt; Found dependencies: HTTP::Server::Simple::PSGI, HTTP::Body, MIME::Types
--&gt; Working on HTTP::Server::Simple::PSGI
[...]
Successfully installed MIME-Types-1.31
Building Dancer-1.3030 ... OK
Successfully installed Dancer-1.3030
&lt;== Installed dependencies for .. Finishing.
8 distributions installed
uwsgi: stopped
uwsgi: ERROR (abnormal termination)
Connection to www.weasel.dotcloud.com closed.
</code></pre>

<p>Oh-oh! Something went wrong!
I checked the log files to see what was it:</p>

<pre><code>$ dotcloud logs weasel.www
#  tail -F /var/log/{supervisor,nginx}/*.log 
[...]
==&gt; /var/log/supervisor/uwsgi.log &lt;==
[...]
Plack::Request is needed by the PSGI handler at /home/dotcloud/perl5/lib/perl5/Dancer.pm line 334
Compilation failed in require at (eval 3) line 1.
[...]
</code></pre>

<p>That&#8217;s it: it&#8217;s clearly missing <code>Plack::Request</code> to be able to handle <code>PSGI</code> requests.
No problem; just add it to the <code>Makefile.PL</code> and deploy again!
This will install the new dependency, and hopefully the service will start!</p>

<pre><code>$ vi Makefile.PL
$ git commit -am "Add Plack::Request as prerequisite also"
[master faa342f] Add Plack::Request as prerequisite also
1 files changed, 1 insertions(+), 0 deletions(-)
$ dotcloud push weasel.www .
# upload . ssh://dotcloud@uploader.dotcloud.com:1060/weasel.www
# git
Warning: Permanently added '[uploader.dotcloud.com]:1060,[174.129.15.77]:1060' (RSA) to the list of known hosts.
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 381 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To ssh://dotcloud@uploader.dotcloud.com:1060/weasel.www
   e4d8d81..faa342f  master -&gt; master
Scheduling build
Fetching logs...
Warning: Permanently added '[www.weasel.dotcloud.com]:3254,[174.129.17.131]:3254' (RSA) to the list of known hosts.
-- Build started...
[...]
Fetched code revision faa342f
--&gt; Working on .
Configuring /home/dotcloud/faa342f ... OK
==&gt; Found dependencies: Plack::Request
--&gt; Working on Plack::Request
[...]
Successfully installed Devel-StackTrace-AsHTML-0.11
Building Plack-0.9976 ... OK
Successfully installed Plack-0.9976
&lt;== Installed dependencies for .. Finishing.
12 distributions installed
uwsgi: started
Connection to www.weasel.dotcloud.com closed.
</code></pre>

<p>And so it did! Let&#8217;s see if my webapp really worked:</p>

<pre><code>$ curl http://www.weasel.dotcloud.com/
Why, hello there!

$ curl http://www.weasel.dotcloud.com/test-123
Hello test123!
</code></pre>

<p>Indeed it did!</p>

<p>There you go, an easy way to deploy a <a href="http://perldancer.org/">Dancer</a> webapp to the cloud!</p>

<p>Here are the sample files I used:</p>

<pre><code>$ cat Makefile.PL
#!/usr/bin/env perl
use ExtUtils::MakeMaker;
WriteMakefile(
    PREREQ_PM =&gt; {
        'Dancer' =&gt; '1.3030',
        'Plack::Request' =&gt; '0.9976',
    },
);


$ cat myapp.pl 
#!/usr/bin/env perl
use Dancer;
get '/' =&gt; sub {
    return "Why, hello there!\n";
};
get '/:name' =&gt; sub {
    my $name = params-&gt;{name};
    $name =~ s/[^a-z0-9 ]//i;
    return "Hello $name!\n";
};
dance;

$ cat app.psgi 
require 'myapp.pl';
</code></pre>

<p>Really, really easy! Thanks <a href="http://www.dotcloud.com/">Dotcloud</a>! And, thanks CPAN and CPAN authors, without which the above certainly would not have been possible!</p>
]]>
    </content>
</entry>

<entry>
    <title>Inline::C optimizations</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2010/09/inlinec-optimizations.html" />
    <id>tag:blogs.perl.org,2010:/users/marco_fontani//56.1007</id>

    <published>2010-09-13T18:03:30Z</published>
    <updated>2010-09-15T02:10:56Z</updated>

    <summary>At the last (first, actually) Glasgow.pm meeting last week, I mentioned to a couple of the people present an instance in which I&apos;ve used the wonderful Inline::C module to replace a chunk of Perl code I couldn&apos;t quite get to...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="mud" label="MUD" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="Perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>At the last (first, actually) <a href="http://glasgow.darkpan.com">Glasgow.pm</a> meeting last week, I mentioned to a couple of the people present an instance in which I've used the wonderful <a href="http://search.cpan.org/dist/Inline/C/C.pod">Inline::C</a> module to replace a chunk of Perl code I couldn't quite get to work fast enough.</p>
]]>
        <![CDATA[<p>I would recommend jumping to the <a href="#post_bottom_nitty_gritty">bottom</a> of the post if you'd like to skip stories and just jump to the code.</p>

<p>After some ooohs, aaahs, and mockery... I said I'd follow up and post exactly the code I was talking about. I'd quite much like to see if the Perl version could be modified to be faster in any way: that would be a great learning experience!</p>

<p>I have been involved in <a href="http://en.wikipedia.org/wiki/MUD">MUD</a> development for a while, and my Anacronia MUD had quite a bit of Italian players at the turn of the century. The MUD went through various iterations before closing down roughly before I moved to Scotland. Since then, I have participated in the development of a couple other MUDs, one of which is still open to this day, adding things like MCCP1/2 support (zlib compression over telnet) and other low-level things like that.</p>

<p>Some time ago I decided to start writing a MUD engine in Perl, using more modern tools like Moose for the objects, and POE for the event loop. I'm still considering using Async but lack good examples :(</p>

<p>Since content for testing and trying out things is hard to come by, I "reused/borrowed" some of the older <a href="http://www.smaug.org">Smaug</a> area files, specifically the "help.are" area file. The file is in a format I know quite well, and basically contains a list of human-readable "man pages" for the MUD, littered with some sigils which the MUD then translates into coloured strings.</p>

<p>Handling these tricky little sigils are the object of the Inline::C optimizations.</p>

<p>Leaving aside the formatting sigils which mean "reset the (foreground|background) color", we're left with the sigils which govern the colors.<br />
For example, the following string can get parsed and produce an ANSI coloured string, with the correct fore/background colour changes:<br />
<code>--^p&WA&yn&Wa&yc&Wr&yo&Wn&yi&Wa &CV4&^--</code><br />
Here's the image of the (unsightly, I agree!) result:<br />
<img src="http://darkpan.com/files/ansi_anacronia_v4.png" /></p>

<p>The format of the sigils is simply an ampersand followed by a colour letter for a foreground color change, and a caret followed by the same colour letter for a background colour change. Capital letters on the foreground set the bold status, etc.</p>

<p>The letters are x, r, g, y, b, p, c, w for black/reset, red, green, yellow and so on</p>

<p>The ansifier does a <code>unpack("C*",$input_string);</code> and then uses a state machine (with state given as the ansifier's parameters) to analyse the character and either output it verbatim, change its internal state, or output a coloured ANSI sequence. This is written in Perl, and works quite well.</p>

<p>A specific bit of the ansifier is the place where the parser is right after a <tt>&</tt> or a <tt>^</tt>: since the next character is supposed to be a color letter, it needs to identify if that's a valid color, and if it is use the corresponding "index number" to build the correct ANSI string. For example, "&x" with no state should output "\e[30m", "&r" with no state should output "\e[31m", etc.</p>

<p>As part of my small MUD test suite, I created a "bot" program which would make a number of connections to the MUD and start shouting coloured strings or reading coloured help pages, or generally stressing out what the server could do. It felt dog slow. Some times I have launched the mud under <a href="http://search.cpan.org/dist/Devel-NYTProf/">Devel::NYTProf</a> to see what was the cause, and was not too surprised to see that one of the topmost subroutines was the one which handled the help pages request.</p>

<p>Well, these help pages don't change that often so they can be parsed once and then cached! That problem out of the way, the ansify() function became the most problematic one. You see, it's called whenever output is sent from the MUD to the player. That is, at every prompt or at every output. Again, I did some caching... but players' input is basically random so caching didn't help too much with this.</p>

<p>Delving in the internals of the report I realised that a very, very long time was spent in that tiny fraction of code which looked up whether a character was one of "xrgybpcw" and what its index should be.</p>

<p>The <a name="post_bottom_nitty_gritty">Perl function</a> I had at the time was along these lines:</p>

<pre><code
>{
    my @colors = map { ord } qw/x r g y b p c w/;
    sub perl_getcolor {
        my $clrchar = shift;
        for ( 0 .. $#colors ) {
            return $_ if ( $clrchar == $colors[$_] );
            return $_ if ( ( $clrchar + 32 ) == $colors[$_] );
        }
        return 255;
    }
}</code></pre>

<p>This works well, but it's quite slow.</p>

<p>If Perl had -funroll-loops, that's where it could be used ;) The resulting "unrolled" Perl subroutine isn't that great either. I have not tested the below, so it may actually be completely wrong!</p>

<pre><code
>{
    #my @colors = map { ord } qw/x r g y b p c w/;
    # 120 114 103 121 98 112 99 119
    sub opt_perl_getcolor {
        #$_[0]+32 == 120 && return 0; # 120 - 32 : 88; etc
        $_[0] == 120 && return 0;
        $_[0] == 88  && return 0; # $_[0]+32 == 120
        $_[0] == 114 && return 1;
        $_[0] == 82  && return 1;
        $_[0] == 103 && return 2;
        $_[0] == 71  && return 2;
        $_[0] == 121 && return 3;
        $_[0] == 89  && return 3;
        $_[0] == 98  && return 4;
        $_[0] == 66  && return 4;
        $_[0] == 112 && return 5;
        $_[0] == 80  && return 5;
        $_[0] == 99  && return 6;
        $_[0] == 67  && return 6;
        $_[0] == 119 && return 7;
        $_[0] == 87  && return 7;
        return 255;
    }
}</code></pre>

<p>In the MUD, I went with the below Inline::C version:</p>

<pre><code
>use Inline C  => <<'END_INLINE_C';
    unsigned char __colors[8] = "xrgybpcw";
    unsigned char getcolor(unsigned char clrchar) {
        char i = 0;
        for ( i = 0; i < 8; i++ ) {
            if (   clrchar     == __colors[i] ) { return i; }
            if ( ( clrchar+32) == __colors[i] ) { return i; }
        }
        return (unsigned char) -1;
    }</code></pre>

<p>I'm aware that the above can be further "optimized" in the same way as the Perl one, of course, but there's not really a huge need for that: premature optimization, yadda yadda yadda</p>

<pre><code
>    unsigned char opt_getcolor(unsigned char clrchar) {
        switch (clrchar) {
            case 120: case 88: return 0;
            case 114: case 82: return 1;
            case 103: case 71: return 2;
            case 121: case 89: return 3;
            case 98:  case 66: return 4;
            case 112: case 80: return 5;
            case 99:  case 67: return 6;
            case 119: case 87: return 7;
            default: return (unsigned char) -1;
        }
    }</code></pre>

<p>How well do the above four functions perform? The code is at <a href="http://darkpan.com/files/ansi--inline-c--vs--perl.pl.txt">ansi--inline-c--vs--perl.pl.txt</a> and the results on my machine below:</p>

<pre
>                          Rate Pure Perl version Opt Perl version Inline::C version Opt Inline::C version
Pure Perl version      <strong>34262/s</strong>                --             -65%              -90%                  -91%
Opt Perl version       98814/s              188%               --              -71%                  -75%
Inline::C version     <strong>337079/s</strong>              884%             241%                --                  -14%
Opt Inline::C version 391645/s             1043%             296%               16%                    --</pre>

<p>The Inline::C version gave me a ~10x better performance than the original Perl one, and it made the function go away from the top of the list of subroutines in which the most time was spent. Now I'm left with POE internals occupying the topmost bits, hence my starting to research the Async territory.</p>

<p>Unrolling the loop on the "optimized Perl version" gave it a x3 performance boost. What other trickery would you have performed to make that Perl subroutine faster?</p>

<p>If you're from <a href="http://glasgow.darkpan.com">Glasgow.pm</a> or come to our meetings, you may want to bring a lightning talk answering the above question ;)<br />Or, you could leave a comment below</p>

<p>Thanks for reading,<br />
-marco-</p>

<p>Updated benchmarks at same link (thanks Illusori!): using a hash lookup is certainly faster, and the array lookup is blazing fast:</p>

<pre style="font-size:0.7em;"
>                  Rate Pure Perl Opt Perl Hash Perl Lookup Perl Inline::C Opt Inline::C
Pure Perl      35294/s        --     -67%      -76%        -80%      -90%          -91%
Opt Perl      106157/s      201%       --      -27%        -39%      -71%          -74%
Hash Perl     146056/s      314%      38%        --        -16%      -60%          -65%
Lookup Perl   174216/s      394%      64%       19%          --      -52%          -58%
Inline::C     363196/s      929%     242%      149%        108%        --          -12%
Opt Inline::C 412088/s     1068%     288%      182%        137%       13%            --</pre>

<p>The new array lookup version's performance means the basic Inline::C version is now only 2x as fast as it; Are there any other optimizations that could be done in Perlish land?</p>]]>
    </content>
</entry>

<entry>
    <title>Resurrecting Glasgow.pm</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2010/08/resurrecting-glasgowpm.html" />
    <id>tag:blogs.perl.org,2010:/users/marco_fontani//56.944</id>

    <published>2010-08-25T22:26:23Z</published>
    <updated>2010-08-25T22:44:42Z</updated>

    <summary>During YAPC::EU mst suggested &quot;why don&apos;t you just start Glasgow.pm?&quot; I talked about it a bit with a friend who&apos;ll be back in the country soon enough and even today at work, and I think we may have enough people...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="glasgow" label="glasgow" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="pm" label="pm" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="scotland" label="scotland" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>During YAPC::EU mst suggested "why don't you just start Glasgow.pm?"</p>

<p>I talked about it a bit with a friend who'll be back in the country soon enough and even today at work, and I think we may have enough people to kickstart the new Perl mongers group.</p>

<p>I know there are several businesses and people in the West of Scotland who either use or like Perl, so I am hoping that enough of them would like to join the group.</p>

<p>I've sent the request to pm.org's support to reinstate the old Glasgow.pm. I will endeavour to bring the mailing list and website up as soon as possible, and will start reaching out to people who use Perl in the area. Dear lazyweb, could you help me?</p>

<p>In contrast with Edinburgh.pm's meetings, which are mostly "social" gatherings in the pub, I would like Glasgow.pm's meetings to be a bit more on the technical side. I am hoping we will be able to secure a good venue for that (crossing fingers!), and that we'll have enough people and interest to have a bunch of talks and lightning talks at each meeting.<br />
Depending on what the consensus is, I think we may end up having a technical meeting one month, and one social meeting the next.</p>

<p>Please spread the word if you think somebody in the area may be interested in coming along, and feel free to contact me both on this blog and via e-mail at mfontani at cpan dot org.</p>

<p>Oh, and I'd be proposing the second tuesday of the month as the meeting's day (Edinburgh.pm's is the fourth Thursday -- tomorrow). This would allow people in either city to attend either meetings.</p>

<p>Wish me good luck! :)<br />
-marco- </p>]]>
        
    </content>
</entry>

<entry>
    <title>SproutCore and Tatsumaki</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2010/05/sproutcore-and-tatsumaki.html" />
    <id>tag:blogs.perl.org,2010:/users/marco_fontani//56.554</id>

    <published>2010-05-15T16:42:46Z</published>
    <updated>2010-05-15T16:53:09Z</updated>

    <summary>I added a Perl backend version of the SproutCore tutorial to the wiki. It was useful to see how Tatsumaki (the new framework by Tatsushiko Miyagawa) worked, and also because PSGI is quite fun to use!...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="plack" label="plack" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tatsumaki" label="tatsumaki" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>I added a <a href="http://wiki.sproutcore.com/Todos+06-Building+with+Perl+and+Tatsumaki">Perl backend version</a> of the SproutCore tutorial to the wiki. It was useful to see how Tatsumaki (the new framework by Tatsushiko Miyagawa) worked, and also because PSGI is quite fun to use!</p>]]>
        <![CDATA[<p>To create it, I simply added a new user on my netbook, fetched <a href="http://xrl.us/cpanminus">cpanm</a> and used it to install the various CPAN modules needed (<a href="http://plackperl.org/">Plack</a>, <a href="http://search.cpan.org/dist/Tatsumaki/">Tatsumaki</a>, <a href="http://search.cpan.org/dist/ORLite/">ORLite</a>).</p>

<p>I followed through the POD for Tatsumaki to get an idea of how the various methods (put, get, post) would have to be implemented. Some things weren't quite clear, and had to reach the source to find out, for example, exactly how to set the HTTP response code.</p>

<p>All in all quite a fun experience. Please do read it and feel free to modify it and give feedback via the comments!</p>

<p>The tutorial is at <a href="http://wiki.sproutcore.com/Todos+06-Building+with+Perl+and+Tatsumaki">wiki.sproutcore.com</a> and is part of the bigger tutorial for Sproutcore, which starts at <a href="http://wiki.sproutcore.com/browse/#view=ViewFolder&param=Tutorials%20-%20Todo%20App">the tuturials page</a>.</p>

<p>Till soon,<br /><br />
-marco-</p>]]>
    </content>
</entry>

<entry>
    <title>Is that perl 5.12 on your netbook?</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2010/04/is-that-perl-512-on-your-netbook.html" />
    <id>tag:blogs.perl.org,2010:/users/marco_fontani//56.475</id>

    <published>2010-04-13T22:38:56Z</published>
    <updated>2010-04-13T23:04:35Z</updated>

    <summary>OH YEAH! Just finished installing the brand spanking new Perl 5.12 on the netbook on my &quot;perl&quot; account, with which I tested already earlier -RC releases with my personal code. It&apos;s fair to say that the user experience has gone...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="git" label="git" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>OH YEAH!</p>

<p>Just finished installing the brand spanking new Perl 5.12 on the netbook on my "perl" account, with which I tested already earlier -RC releases with my personal code.</p>

<p>It's fair to say that the user experience has gone a long way from the "old days" of manual configuration, installation, swearing and $ENV madness.
Hell, one doesn't even need local::lib anymore!</p>

<p>All I had to do to test 5.12 after creating my "perl" account was:</p>

<pre><code>curl -LO http://xrl.us/perlbrew
chmod +x ./perlbrew
./perlbrew install
rm perlbrew 
~/perl5/perlbrew/bin/perlbrew init
echo 'source /home/perl/perl5/perlbrew/etc/bashrc' &gt;&gt; .bashrc  
source .bashrc
echo $PATH
perlbrew install perl-5.12.0
# wait some time..
perlbrew switch perl-5.12.0
perl -V
</code></pre>

<p>There you go, shiny new Perl to be used!</p>

<pre><code>git clone git://github.com/miyagawa/cpanminus.git
cd cpanminus
make test install
cpanm YAML
# and YAML's installed
perl -E'use YAML;say Dump({"sound"=&gt;["YAML!"]})'
</code></pre>

<p>On my desktop machine instead I started versioning ~/perl5/ under Git starting with -RC4, adding and committing all the cpanm-installed modules as I went.
This helped a lot with remembering which modules got installed (although perldoc perllocal also keeps track of that!) in order to install them again when testing the new -RC or the new 5.12. Although, I wasn't entirely consistent with the naming of the commits. Meh.</p>

<p>I only had a couple issues with modules like Gearman::XS which required the latest and greatest library which wasn't available on Ubuntu Lucid. I simply reset the Git tree when the builds didn't work. For Gearman::XS I downloaded, committed, tested and installed the latest version (having it Git-versioned helps) and then rebuilt Gearman::XS with a couple environment variables (also noted on the commit logs).</p>

<p>One learns from their mistakes, so I'll use another format for the commit messages when I'll install and test 5.12 on my desktop account: I'll make sure to "tag" the cpanm commits as such (for example, with which cpanm command I issued and with the list of additional modules installed <em>after</em> the blank line in the Git commit) and the modules requiring installation of other libraries also in a different and sensible way.</p>

<p>The idea would be to be able to do something like the following, and being able to have a good list of commands I need to type to have all my favourite modules on the new Perl version with minimum effort:</p>

<pre><code>git log --pretty=oneline | cut -d ' ' -f 2- | tac
</code></pre>

<p>From there, I'll just go through my ~/GIT/ and run the test suites there. Maybe I'll have some code ready for the next post.</p>

<p>For now, I just want to say <em>THANKS</em> to the wonderful Perl 5 Porters who did manage to get the next stable release out as promised.
I look forward to 5.14!</p>

<p>-marco-</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Google Talk with Perl</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2010/03/google-talk-with-perl.html" />
    <id>tag:blogs.perl.org,2010:/users/marco_fontani//56.353</id>

    <published>2010-03-13T15:36:10Z</published>
    <updated>2010-03-14T19:08:00Z</updated>

    <summary>I was looking for a way to send a Google Talk message (via Perl) whenever a certain something occurs, and thought it&apos;d be a simple task since Google Talk uses the Jabber protocol, XMPP and all that. Boy was I...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="perlgtalk" label="perl gtalk" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>I was looking for a way to send a Google Talk message (via Perl) whenever a certain something occurs, and thought it'd be a simple task since Google Talk uses the Jabber protocol, XMPP and all that.</p>

<p>Boy was I wrong.</p>

<p>I found some code on the 'net which used Net::XMPP::Client to create the connection to talk.google.com, authenticate and send the message. It just didn't work.</p>

<p>Turning some debugging on revealed I was getting an "incorrect-authz" error from Google. The username and password weren't at fault (that'd be another error).</p>

<p>As from <a href="http://code.google.com/apis/talk/jep_extensions/jid_domain_change.html">this page</a> the reason for the authorisation failure has to be found in the feature called "JID Domain discovery".</p>

<p>This is an example of the string used to authenticate to gtalk:</p>

<pre><code>&lt;auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
    mechanism='PLAIN'
    xmlns:ga='http://www.google.com/talk/protocol/auth'
    ga:client-uses-full-bind-result='true'&gt;
    HASHED_USER+PASS_INFO
&lt;/auth&gt;
</code></pre>

<p>The difference between what Google needs and what the Jabber modules give is enough for the Google servers to give an error.</p>

<p>The following program connects to Google Talk and sends a message to a user specified (available at <a href="http://darkpan.com/files/notify-via-jabber.pl.txt">http://darkpan.com/files/notify-via-jabber.pl.txt</a> as well):</p>

<pre><code>#!/usr/bin/perl -w
use strict;
use warnings;
use Net::XMPP;
{
    # monkey-patch XML::Stream to support the google-added JID
    package XML::Stream;
    no warnings 'redefine';
    sub SASLAuth {
        my $self = shift;
        my $sid  = shift;
        my $first_step =
            $self-&gt;{SIDS}-&gt;{$sid}-&gt;{sasl}-&gt;{client}-&gt;client_start();
        my $first_step64 = MIME::Base64::encode_base64($first_step,"");
        $self-&gt;Send( $sid,
            "&lt;auth xmlns='" . &amp;ConstXMLNS('xmpp-sasl') .
            "' mechanism='" .
            $self-&gt;{SIDS}-&gt;{$sid}-&gt;{sasl}-&gt;{client}-&gt;mechanism() .
            "' " .
            q{xmlns:ga='http://www.google.com/talk/protocol/auth'
            ga:client-uses-full-bind-result='true'} . # JID
            "&gt;".$first_step64."&lt;/auth&gt;");
    }
}
my $username  = shift or die "$0: username needed";
my $password  = shift or die "$0: password needed";
my $resource  = shift or die "$0: client handle needed";
my $recipient = shift or die "$0: need recipient address";
my $message   = shift or die "$0: need message to send";
my $conn   = Net::XMPP::Client-&gt;new;
my $status = $conn-&gt;Connect(
    hostname =&gt; 'talk.google.com',
    port =&gt; 5222,
    componentname =&gt; 'gmail.com',
    connectiontype =&gt; 'tcpip',
    tls =&gt; 1,
);
die "Connection failed: $!" unless defined $status;
my ($res,$msg) = $conn-&gt;AuthSend(
    username =&gt; $username,
    password =&gt; $password,
    resource =&gt; $resource, # client name
);
die "Auth failed ",
    defined $msg ? $msg : '',
    " $!"
    unless defined $res and $res eq 'ok';
$conn-&gt;MessageSend(
    to =&gt; $recipient,
    resource =&gt; $resource,
    subject =&gt; 'message via ' . $resource,
    type =&gt; 'chat',
    body =&gt; $message,
);
</code></pre>

<p>Use it to send a chat from youruser@gmail.com to another@googlemail.com like so:</p>

<pre><code>perl notify.pl youruser PASSWORD 'notify v1.0' another@googlemail.com 'this is a test message'
</code></pre>

<p>I hope this will be of help to somebody :)</p>

<p>-marco-</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Cloud laziness part 1: creating a CloudServers server instance</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2009/12/cloud-laziness-part-1-creating-a-cloudservers-server-instance.html" />
    <id>tag:blogs.perl.org,2009:/users/marco_fontani//56.81</id>

    <published>2009-12-08T08:47:25Z</published>
    <updated>2009-12-08T09:03:25Z</updated>

    <summary>The following is ongoing on my private branch of the CPAN dist Net::RackSpace::CloudServers, in which I&apos;m creating an App::Cmd interface to the module: okram@bluedesk: (with_app_cmd) ~/GIT/Net-RackSpace-CloudServers$ perl cloudservers.pl create \ --name=mfapitest --imagename karmic --flavorname 256 --verbose Server name: mfapitest Metadata:...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="github" label="github" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p>The following is ongoing on my private branch of the CPAN dist <a href="http://search.cpan.org/dist/Net-RackSpace-CloudServers/">Net::RackSpace::CloudServers</a>, in which I'm creating an <a href="http://search.cpan.org/dist/App-Cmd/">App::Cmd</a> interface to the module:</p>

<pre>okram@bluedesk: (with_app_cmd)
~/GIT/Net-RackSpace-CloudServers$ perl cloudservers.pl create \
  --name=mfapitest --imagename karmic --flavorname 256 --verbose
Server name: mfapitest
Metadata: 
Paths: 
Image id 14362 named Ubuntu 9.10 (karmic)
Flavor id 1 named 256 server
Creating new server...
Created server ID 124999
root password: mfapitestXXXXXXX
Public IP: 174.143.242.999
Private IP: 10.176.140.999
Server status: ACTIVE progress: 100..
Server now available!

</pre>

<p>The same is indeed doable with the sample <a href="http://cpansearch.perl.org/src/MFONTANI/Net-RackSpace-CloudServers-0.09_20/scripts/newserver.pl">scripts/newserver.pl</a> in the dist -- and I also need to use <a href="http://cpansearch.perl.org/src/MFONTANI/Net-RackSpace-CloudServers-0.09_20/scripts/deleteserver.pl">scripts/deleteserver.pl</a> to destroy the test instance -- but I assume that a command-line interface may be useful in the longer term to scale up/down specific instances, create N new servers in a shared IP group, or destroy no longer needed instances.</p>

<p>The command was pretty painless to write, and most of it was the validate_args routine... </p>

<p>As usual, comments would be much appreciated!<br />
Till soon,<br />
-marco-</p>]]>
        
    </content>
</entry>

<entry>
    <title>Git - inhibit commit if modules don&apos;t compile</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2009/11/git---inhibit-commit-if-modules-dont-compile.html" />
    <id>tag:blogs.perl.org,2009:/users/marco_fontani//56.65</id>

    <published>2009-11-29T15:48:01Z</published>
    <updated>2009-11-29T15:52:00Z</updated>

    <summary>Sometimes I forget to run Perl base tests for my modules, before committing changes. As to what happens, I end up committing something that doesn&apos;t quite compile ;) Luckily Git has a pre-commit hook one can use to run at...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="git" label="git" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="hooks" label="hooks" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[Sometimes I forget to run Perl base tests for my modules, before committing changes. As to what happens, I end up committing something that doesn't quite compile ;)

Luckily Git has a pre-commit hook one can use to run at least the "compile" tests.

The following aborts the commit if the t/00*.t tests (usually the "do all modules compile?" tests) in the repository don't run correctly; stick it in <code>.git/hooks/pre-commit</code>:


<code><pre>#!/usr/bin/perl
# Runs modules' "compiles" tests before committing
# Dies (halting commit) if they don't compile
print "pre-commit => testing..\n";
do {qx{
  prove -Ilib t/00*.t
}} or die <<'DIEMSG';
pre-commit => ERRORS:
$@
DIEMSG
print "pre-commit => test OK\n";</pre></code>

This is an example of a 00-load.t file, that can literally be dropped-in the t/ directory:

<code><pre>use strict;
use warnings;
use Test::More;
use File::Find::Rule;
 
my @files = File::Find::Rule->name('*.pm')->in('lib');
plan tests => ~ ~ @files;
 
for (@files) {
  s/^lib.//;
  s/.pm$//;
  s{[\\/]}{::}g;
 
  ok(
    eval "require $_; 1",
    "loaded $_ with no problems",
  );
}</code></pre>

<code>File::Find::Rule</code> is one of the golden gems found on CPAN, rclamp++!
<p>
Till soon,<br />
-marco-</p>]]>
        
    </content>
</entry>

<entry>
    <title>CloudServers Perl module - 0.09_10</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/marco_fontani/2009/11/rackspace-cloudservers-perl-module---009-10.html" />
    <id>tag:blogs.perl.org,2009:/users/marco_fontani//56.31</id>

    <published>2009-11-22T17:21:12Z</published>
    <updated>2009-11-22T18:22:05Z</updated>

    <summary>perl -E&apos;say join &quot; &quot;, reverse world, hello&apos; # :) I&apos;ve finally found some time to play again with the Rackspace API manual, and added a couple features to the Net-RackSpace-CloudServers module I hadn&apos;t touched since moving home some months...</summary>
    <author>
        <name>Marco Fontani</name>
        
    </author>
    
    <category term="perlgithub" label="perl github" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/marco_fontani/">
        <![CDATA[<p><code>perl -E'say join " ", reverse world, hello' # :)</code></p>

<p>I've finally found some time to play again with the <a href="http://www.rackspacecloud.com/">Rackspace</a> API manual, and added a couple features to the <tt>Net-RackSpace-CloudServers</tt> module I hadn't touched since moving home some months ago.</p>

<p>The project is semi-alive on <a href="http://github.com/mfontani/Net-RackSpace-CloudServers/">http://github.com/mfontani/Net-RackSpace-CloudServers/</a>, and the latest 0.09_10 <i>development</i> version should be on CPAN soon.</p>

<p>It's basically a one-to-one adaptation of the Rackspace API document available at <a href="http://www.rackspacecloud.com/cloud_hosting_products/servers/api">http://www.rackspacecloud.com/cloud_hosting_products/servers/api</a>.</p>

<p>On the scripts/ directory there are some examples on how to use the module: it's possible to list all images, flavors, and servers you own, as well as delete servers by ID or create new servers in what I think is quite a simple syntax.</p>

<p>As an example, let's delete that pesky server whose ID's 666:
<code>
  use strict; use warnings; use Net::RackSpace::CloudServers;
  my $cs = Net::RackSpace::CloudServers->new(
    user => $ENV{'CLOUDSERVERS_USER'},
    key  => $ENV{'CLOUDSERVERS_KEY'},
  );
  my @servers = $CS->get_server_detail;
  my $srv_666 = ( grep { $_->id == 666 } @servers )[0];
  die "No such server id 666\n" if ( !defined $srv_666 );
  $srv_666->delete_server(); # dies in case of error
  print "Server #666 deleted\n";
</code></p>

<p>On a branch not on Github yet, I'm working on an <tt>App::Cmd</tt> interface to it, as well.</p>

<p>Any comments at all would be truly appreciated, as this is my first module I'm trying to get on CPAN ;)</p>

Till soon,<br />
-marco-]]>
        
    </content>
</entry>

</feed>
