Yanick's Journal
http://use.perl.org/~Yanick/journal/
Yanick's use Perl Journalen-ususe Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners.2012-01-25T02:23:29+00:00pudgepudge@perl.orgTechnologyhourly11970-01-01T00:00+00:00Yanick's Journalhttp://use.perl.org/images/topics/useperl.gif
http://use.perl.org/~Yanick/journal/
Breaking off from the use.perl.org mothership
http://use.perl.org/~Yanick/journal/38951?from=rss
<p>
For the last couple of months, as a concession between
visibility and control, I'd been double-posting my blog
entries both here and on my
personal blog.
But now that my blog is registered on both the
<a href="http://perlsphere.net/">Perlsphere</a> and
<a href="http://ironman.enlightenedperl.org/">IronMan</a> aggregators,
the need for the second posts here has dwindled. So... I'm going
on a limb and tentatively turn off the echoing.
See y'all on <a href="http://babyl.dyndns.org/techblog">Hacking Thy Fearful
Symmetry</a>!</p>Yanick2009-05-10T23:40:55+00:00journalRuhr.pm: Die Meister des Psycho-Lamas
http://use.perl.org/~Yanick/journal/38840?from=rss
<p> <i>reposted from <a href="http://babyl.dyndns.org/techblog">Hacking Thy Fearful Symmetry</a> </i> </p><p>Last month, thanks to a concerted effort of German Perl Mongers[1]
I was able to meet with the wonderful folks of
<a href="http://ruhr.pm.org/">Ruhr.pm</a>. </p><p>It turns out that not only the Ruhr-area mongers are
a superlatively friendly bunch, but they
have pretty <a href="http://ruhr.pm.org/material.psp">cool presentations</a> too. </p><p>The feature presentation of the night was
<a href="http://ruhr.pm.org/files/fuse/docshot/">Fuse mit Perl</a>,
by Simon Wilper. After he was done, I also got treated with a
quick replay of two previous presentations dealing with image
manipulation. <a href="http://ruhr.pm.org/files/opencv/docshot">One</a>
was about openCV, a facial recognition software,
and its Perl interface, and the other one was about the <a href="http://ruhr.pm.org/files/imagemagick/docshot">uses of
Image::Magick</a>,
including the detailed instructions on how to create a psycho-llama.
That last bit, I daresay, was worth the trip to Germany
all by itself. The script to create the thing is in the <a href="http://ruhr.pm.org/files/imagemagick/imagemagick-beispiele.tar.gz">presentation companion tarball</a>, check it out (well, unless you suffer from epilepsy, in which case you want to stay as far away as possible).</p><p>So, bottom-line: Ruhr.pm rocks big time. If you're ever passing in the vicinity, I highly recommend paying them a visit.<nobr> <wbr></nobr>:-)</p><p>[1] Renée Bäcker saw my use.perl.org blog entry and forwarded the
information to Ruhr.pm, Veit Wahlich -- fearless leader of the Ruhrgebiet mongers --
contacted me and arranged the details, and René Knopp was dispatched
to pick me up from the train station. Many thanks to the whole
bunch!</p>Yanick2009-04-22T00:31:18+00:00journalJust another Perl Ausländer
http://use.perl.org/~Yanick/journal/38591?from=rss
<p>(cross-posted from <a href="http://babyl.dyndns.org/techblog">Hacking Thy Fearful Symmetry</a>)</p><p>Ever since I've learned about the existence of
<a href="http://www.perl-magazin.de/">$foo - Perl Magazin</a>, I've
been awfully curious to take a peek at it.
Unfortunately, they don't ship subscriptions internationally.
So I went for the obvious workaround: I hunted high and low for
the loveliest German lass I could find, asked her to marry me,
and coaxed her family to get and forward me a subscription for
the magazine as this year's Christmas gift.
Worked like a charm.</p><p>
And it was worth it too. The magazine is even better than
I expected, and it's high praises to the authors that
I learned quite a few things from the articles even though
my German is still at a protozoic stage. Whether you're a German
wanting to learn Perl, or a Perl hacker wanting to learn German,
I heartily recommend it.</p><p>And talking of Germany, I'll embark tomorrow on a three-week vacation trip across
the republic. If there are any Perl mongers meeting this month around Duisburg,
Morsbach or Schwieberdigen who wouldn't mind having an Ausländer in
their midst, please feel free to drop me an email.<nobr> <wbr></nobr>:-)</p>Yanick2009-03-04T18:28:37+00:00journalVariation on the Faces of CPAN
http://use.perl.org/~Yanick/journal/38186?from=rss
<p>Faces of CPAN + GD::Image + blissfully idle holiday morning = <a href="http://babyl.dyndns.org/perl/faces_of_cpan/">this</a>.</p>Yanick2008-12-30T18:26:27+00:00journalCPAN Patching with Git
http://use.perl.org/~Yanick/journal/38180?from=rss
<p>A few months ago, brian posted a blog entry
about
<a href="http://use.perl.org/~brian_d_foy/journal/37664">patching modules using Git</a>.
In the ensuing discussion, I pointed at a possible way to
automatise the process a step further by punting the generated
patch to rt.cpan.org. The hack was well-received and, with
(very) minimal coaxing, I was subsequently convinced to
expand on the idea for the Perl Review.</p><p>The resulting piece is now available in
<a href="http://theperlreview.com/">TPR 5.1</a>. In the article, the
initial command-line hack has morphed into
four scripts -- <code>git-cpan-init</code>, <code>git-cpan-clone</code>,
<code>git-cpan-update</code> and <code>git-cpan-sendpatch</code> -- that
pretty much take care of all the administrative
overhead of module patching. In most cases,
grabbing a distro, fixing a bug and sending the
patch can be done in four lines:</p><blockquote><div><p> <tt> $ git cpan-init Some::Module<br> $ git checkout -b mypatch<br> <nobr> <wbr></nobr>...hack hack hack...<br> $ git rebase -i cpan<br> $ git cpan-sendpatch</tt></p></div> </blockquote><p>And, no, the lack of hyphen between <code>git</code> and <code>cpan-X</code>
isn't a typo; the article also covers how
to seamlessly integrate the new scripts into the
git infrastructure (as Edna Mode would say,
<i>it's a non-feature, dahling</i>).</p><p>Of course, I'm burning to say more, but I'll have to stop here.
To know the whole story, you'll have to wait for The Perl Review
to land in your mailbox (you are subscribed to TPR, <i>right?</i>).</p><p> <i>cross-posted from <a href="http://babyl.dyndns.org/techblog">Hacking Thy Fearful Symmetry</a>.</i> </p>Yanick2008-12-29T18:32:52+00:00journalintroducing Dist::Release
http://use.perl.org/~Yanick/journal/37852?from=rss
<p>(<i>cross-posted from
<a href="http://babyl.dyndns.org/techblog">Hacking Thy Fearful Symmetry</a> </i>)
</p><p>I know, I know, there's already more module release managers out there
than there are Elvis impersonators in Vegas. Still, module releasing
seems to
be a very personal kind of itch, and like so many before
I couldn't resist and
came up with my very own scratching stick.</p><p>Of course, I've tried Module::Release. But, although
it is intended to be customized to suit each author's specific needs,
one has to dig fairly deep in the module's guts to do so. What I
really wanted was something even more plug'n'play, something that would
be brain-dead easy to plop new components in. Hence Dist::Release.</p><p>In Dist::Release, the release process is seen as a sequence of steps.
There are two different kind of steps: checks and actions.
Checks are non-intrusive verifications (i.e., they're
not supposed to touch anything), and actions are the steps
that do the active part of the release. When one launches
a release, checks are done first. If some fail, we abort the process.
If they all pass, then we are good to go and the actions are done as well. </p><p>
<b>Implementing a check</b>
</p><div><p>To create a check, all that is needed is one module with a 'check' method.
For example, here is the code to verify that the distribution's MANIFEST
is up-to-date:</p><blockquote><div><p> <tt> package Dist::Release::Check::Manifest::Build;<br> <br> use Moose;<br> <br> use IPC::Cmd 'run';<br> <br> extends 'Dist::Release::Step';<br> <br> sub check {<br> my $self = shift;<br> <br> $self->diag( q{running 'Build distcheck'} )<br> <br> my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =<br> run( command => [qw#<nobr> <wbr></nobr>./Build distcheck #] );<br> <br> return $self->error( join '', @$full_buf )<br> if not $success or grep<nobr> <wbr></nobr>/not in sync/ => @$stderr_buf;<br> }<br> <br> 1;</tt></p></div> </blockquote><p>Dist::Release considers the check to have failed if there is any call made
to <code>error()</code>. If there is no complain, then it assumes that everything is
peachy.</p></div><p>
<b>Implementing an action</b>
</p><div><p>Actions are only marginally more complicated than checks. The module
implementing the action can have an optional <code>check()</code> method, which is
going to be run with all the other checks, and must have a <code>release()</code>,
which make the release-related changes.</p><p>For example, here's the CPANUpload action:</p><blockquote><div><p> <tt> package Dist::Release::Action::CPANUpload;<br> <br> use Moose;<br> <br> use CPAN::Uploader;<br> <br> extends 'Dist::Release::Action';<br> <br> sub check {<br> my ($self) = @_;<br> <br> # do we have a pause id?<br> unless ($self->distrel->config->{pause}{id}<br> and $self->distrel->config->{pause}{password} ) {<br> $self->error('pause id or password missing from config file');<br> }<br> }<br> <br> sub release {<br> my $self = shift;<br> <br> $self->diag('verifying that the tarball is present');<br> <br> my @archives = <*.tar.gz> or return $self->error('no tarball found');<br> <br> if ( @archives > 1 ) {<br> return $self->error( 'more than one tarball file found: ' . join ',',<br> @archives );<br> }<br> <br> my $tarball = $archives[0];<br> <br> $self->diag(&quot;found tarball: $tarball&quot;);<br> <br> $self->diag(&quot;uploading tarball '$tarball' to CPAN&quot;);<br> <br> my ( $id, $password ) =<br> map { $self->distrel->config->{pause}{$_} } qw/ id password<nobr> <wbr></nobr>/;<br> <br> $self->diag(&quot;using user '$id'&quot;);<br> <br> my $args = { user => $id, password => $password };<br> <br> unless ( $self->distrel->pretend ) {<br> CPAN::Uploader->upload_file( $tarball, $args );<br> }<br> }<br> <br> 1;</tt></p></div> </blockquote><p>As for the <code>check()</code>, Dist::Release figures out that a <code>release()</code> failed
if there's a call to <code>error()</code>. </p></div><p>
<b>Configuring for a module</b>
</p><div><p>Configuration is done via a 'distrelease.yml' file dropped in the root
directory of the project. The file looks like this:</p><blockquote><div><p> <tt> pause:<br> id: yanick<br> password: hush<br> checks:<br> - VCS::WorkingDirClean<br> - Manifest<br> actions:<br> - GenerateDistribution<br> - CPANUpload<br> - Github</tt></p></div> </blockquote><p>It's pretty self-explanatory. The checks and actions are applied in the order
they are given in the file.</p></div><p>
<b>Crying havoc...</b>
</p><div><p>And once the configuration file is present, all that remains to be done is to run <code>distrelease</code>, sit back and enjoy the show:</p><blockquote><div><p> <tt> $ distrelease<br> Dist::Release will only pretend to perform the actions (use --doit for the real deal)<br> running check cycle...<br> regular checks<br> VCS::WorkingDirClean [failed]<br> working directory is not clean<br> # On branch master<br> # Changed but not updated:<br> # (use &quot;git add <file>...&quot; to update what will be committed)<br> #<br> # modified: Build.PL<br> # modified: Changes<br> # modified: README<br> # modified: distrelease.yml<br> # modified: lib/Dist/Release/Check/Manifest.pm<br> # modified: script/distrelease<br> #<br> # Untracked files:<br> # (use &quot;git add <file>...&quot; to include in what will be committed)<br> #<br> # STDOUT<br> # a<br> # blog<br> # xml<br> # xt/dependencies.t<br> # xxx<br> no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)<br> Manifest [failed]<br> No such file: lib/Dist/Release/Action/DoSomething.pm<br> Not in MANIFEST: a<br> Not in MANIFEST: blog<br> Not in MANIFEST: lib/Dist/Release/Action/Github.pm<br> Not in MANIFEST: STDOUT<br> Not in MANIFEST: xml<br> Not in MANIFEST: xt/dependencies.t<br> Not in MANIFEST: xxx<br> MANIFEST appears to be out of sync with the distribution<br> pre-action checks<br> GenerateDistribution [passed]<br> no check implemented<br> CPANUpload [passed]<br> Github [passed]<br> 2 checks failed<br> some checks failed, aborting the release</tt></p></div> </blockquote></div><p>
<b>Getting the good</b>
</p><div><p>A <a href="http://search.cpan.org/dist/Dist-Release/">first release of Dist::Release</a>
is already waiting for you on CPAN. It's beta, has no documentation, is
probably buggy as hell, but it's there. And the code is also available on
<a href="http://github.com/yanick/dist-release/tree/master">Github</a>. Comments,
suggestions, forks and patches are welcome, as always.<nobr> <wbr></nobr>:-)</p></div>Yanick2008-11-11T04:01:41+00:00journalMe at OsBootCamp 8
http://use.perl.org/~Yanick/journal/37373?from=rss
<p> <a href="http://www.osbootcamp.org/">OS Bootcamp</a> is a cool initiative to inform and initiate
university students to the wonders of the Open Source world.</p><p> <a href="http://www.osbootcamp.org/index.php?page=yow8">OsBootCamp 8</a>,
which took place on August 28th,
was about interpreted programming languages. On the agenda
were short
introductions of the three
big kids on the block (Perl, Python and Ruby).
And yup, the honor
to ramble about Perl was given to li'll old me. For
the morbidly curious, there's
a
<a href="http://www.virtualvernisage.com/archives/2008_aug29_633556336613281250/?hideSocial=false&archiveID=85">video</a>
of the resulting show.<nobr> <wbr></nobr>:-)
</p>Yanick2008-09-06T15:06:01+00:00journalPasting repository info on CPAN page
http://use.perl.org/~Yanick/journal/37168?from=rss
<p>Out of the comments generated
by a post by <a href="http://use.perl.org/~grink/journal/37141">grink</a>,
I've learned that the location of the distribution's repository
can be inserted in the
<a href="http://module-build.sourceforge.net/META-spec-current.html#resources">META.yml</a>.
Neato! </p><p>And when grink asked if someone could come up with a Greasemonkey
script to extract that information and show it on the distro's
page... well, that's no simian fun I could let pass untackled.
The
resulting greasemonkey script can be found
<a href="http://userscripts.org/scripts/show/31660">here</a>.</p>Yanick2008-08-13T01:58:05+00:00journalMohlohpoly game
http://use.perl.org/~Yanick/journal/37095?from=rss
<p>While working on
<a href="http://search.cpan.org/~yanick/WWW-Ohloh-API/">WWW::Ohloh::API</a>,
I caught myself wondering
how one could use <a href="http://www.ohloh.com/">Ohloh</a>
for some kind of game. A few bus trips later with no
book to keep my mind out of trouble, I came up with the variant
of Monopoly given below. I'm recording it here to get it out
of my system. Maybe one day, when I'll have time (ah!),
I'll implement it. It'd be worth it just for the fun of
collecting famous hackers like Pokémons.<nobr> <wbr></nobr>:-)</p><p>
Rules
</p><ul>
<li>Every player start with a given amount of "money" (or moohlah). </li><li>Developers can be bought for a price inversely proportional to their
Ohloh rank. A developer can only
be
owned by a single player at any given time. </li><li>A player can sell one of his developers at market price at any time.
The player can also sell a developer directly to another player for
any agreed price between them. Or he can auction the developer in
an open auction to the rest of the players. </li><li>Any time a developer receives a kudo, the player owning him or her
gets a dividend proportional to the rank of the kudo giver. </li><li>If a player possesses all developers of a project, they "own"
that project. </li><li>Each turn, each player gets to "use" a random project picked from
the set of all projects owned by a player, and must
pay a fee proportional to the review score and number of users
of that project. If the player doesn't have enough moohlah to
pay up, one his or her developer is picked at random and sold
at market value until the player becomes solvent again. If
the player ends up without moohlah or hackers, he or she goes
under.</li></ul>Yanick2008-08-05T00:55:58+00:00journalObject::InsideOut Cheatsheet
http://use.perl.org/~Yanick/journal/36961?from=rss
<p>Everybody is raving about <a href="http://search.cpan.org/~stevan/Moose/">Moose</a> these days, but I must say that
I still prefer
<a href="http://search.cpan.org/~jdhedden/Object-InsideOut">Object::InsideOut</a>. One of the things I love about
OIO is its extensive documentation
(70 glorious pages worth of pod!). One of things that I find daunting about it is,
well,
finding back the attribute I'm looking for as I thumb through
those seventy-something blasted pages. </p><p>So I made myself a
<a href="http://babyl.dyndns.org/perl/oio/oio-cheatsheet.pdf">cheatsheet</a>. It's not
complete yet, but it's already containing what most mortals
would use on a daily basis.</p><p>(btw, I've used <a href="http://www.scribus.net/">Scribus</a>
to generate the 3-fold. Although I really,
really want to like that software, I must say that it makes me
miss Quark XPress real bad. If anyone has any suggestion for an
alternative Desktop Publishing tool, please feel free to let me know.)</p>Yanick2008-07-20T01:31:14+00:00journalBart on Git
http://use.perl.org/~Yanick/journal/36922?from=rss
<p> <a href="http://www.jukie.net/~bart/blog">Bart Trojanowki</a> gave a Git presentation to the Ottawa Ruby Group earlier
this month (I attended as a deep undercover Perl mole). The slides and the
podcast are now available at
<a href="http://excess.org/article/2008/07/ogre-git-tutorial">http://excess.org/article/2008/07/ogre-git-tutorial</a>.</p><p>Very good presentation, meant as an introduction to the beast, but
containing enough little nudgets to have anyone learn something from
it.</p>Yanick2008-07-16T02:13:07+00:00journalBring the blog back hooome
http://use.perl.org/~Yanick/journal/36896?from=rss
<p>Just to say that my main blog is going to be <a href="http://babyl.dyndns.org/techblog">here</a> (although I'm probably going to echo my posts at use.perl.org for a while still). </p><p>I love the soapbox that use.perl.org provides but the site's blogging interface is, shall we say, a tad archaic and on the painful side. I can live with the html format of entries, but many times I've longed for something a little bit more code snippet-friendly. So, when <a href="http://perlsphere.net/">Perlsphere</a> appeared at the horizon, the temptation to repatriate my blog on my own server became just too great to ignore...</p><p>Of course, considering that it's a blog about Perl blabbering, using some PHP blog engine would have not felt quite right. So I decided to experiment with <a href="http://search.cpan.org/~jrockway/Angerwhale">Angerwhale</a>. It's a pretty nifty engine, but it has a few rough edges. In fact, I already began to hack and patch at it... expect some entries about it sometimes soon.<nobr> <wbr></nobr>:-)</p>Yanick2008-07-11T03:31:53+00:00journalTest::Class + Test::Group
http://use.perl.org/~Yanick/journal/36734?from=rss
<p>
I've been playing with
<a href="http://search.cpan.org/~adie/Test-Class/">Test::Class</a>
lately and,
I must say, it's a heck of a nice module. Only thing that
I wish it had is the possibility to report each test as
a single pass/failure, no matter the number of assertions
done in the function. Just like
<a href="http://search.cpan.org/~domq/Test-Group">Test::Group</a> does.</p><p>Hmmm... But wait a second. Could it be possible to somehow stuff the
caramel-like sweetness of Test::Group in the smooth chocolatey
wrapping of Test::Class? Turns out that yes, it's perfectly possible! And
even more, without even having to muck with the guts of either
modules:</p><blockquote><div><p> <tt>package Some::TestSuite;<br> <br>use base qw/ Test::Class<nobr> <wbr></nobr>/;<br>use Test::Group;<br>use Test::More;<br> <br>sub Test<nobr> <wbr></nobr>:ATTR(CODE,RAWDATA) {<br> my ( $pkg, $funct, $code ) = @_;<br> <br> no warnings; # black magic starts here<br> <br> my $func_name = *{$funct}{NAME};<br> my $fullname = $pkg.'::'.$func_name;<br> <br> *{$funct} = sub {<br> print "begin test [", scalar localtime, "]\n";<br> Test::Group::test( $fullname => \&{$code} );<br> print "end test [", scalar localtime, "]\n";<br> };<br> <br> Test::Class::Test( @_ );<br>}<br> <br>sub aTest : Test {<br> ok 1, 'eins';<br> ok 1, 'zwei';<br> ok 1, 'drei';<br>}<br> <br>sub otherTest : Test {<br> ok 1, 'un';<br> ok 0, 'deux';<br> ok 1, 'trois';<br>}<br> <br>Some::TestSuite->runtests;</tt></p></div> </blockquote><p>Which gives</p><blockquote><div><p> <tt>$ perl test.t<br>1..2<br>begin test [Thu Jun 19 22:17:16 2008]<br>ok 1 - Some::TestSuite::aTest<br>end test [Thu Jun 19 22:17:16 2008]<br>begin test [Thu Jun 19 22:17:16 2008]<br># Failed test 'deux'<br># in a.t at line 32.<br>not ok 2 - Some::TestSuite::otherTest<br># Failed test 'Some::TestSuite::otherTest'<br># at a.t line 17.<br># (in Some::TestSuite->otherTest)<br>end test [Thu Jun 19 22:17:16 2008]<br># Looks like you failed 1 test of 2.</tt></p></div> </blockquote><p>This method, though, has two modest caveats:</p><ol>
<li>A failed assertion will be given with the correct line,
but the test itself will be reported as being located inside
the Test() function.</li><li>Test fixtures have to be declared as having 1 test (i.e.,
it has to be <i>sub mySetup<nobr> <wbr></nobr>:Test(setup => 1) {<nobr> <wbr></nobr>.. })</i></li></ol>Yanick2008-06-20T01:50:04+00:00journalWhy I am passionate about Perl
http://use.perl.org/~Yanick/journal/36384?from=rss
<p>
<b>The person who introduced me to Perl showed me that</b><nobr> <wbr></nobr>... well,
in my case it's kinda of a spurious question,
considering that no-one really properly
introduced me to the
language. At the time, I just happened to look around for a good
scripting
language to learn and saw that Perl was one of the languages used by
some members of my team. I bought the Camel book, dived in and...
the rest is pretty much history.</p><p>
<b>I first starting using Perl to </b> do small shell stuff. If
I recall correctly,
the first script I touched was a load balancer that was monitoring
a unix corral and launching
queued jobs on the less busy machines. Then I began
to use it to diddle text files (change 'class Foo' to 'class Bar' in
my source code, figure out how many functions are in each file, etc.).
And then came the <a href="http://www.tipjar.com/games/solitaire/wheels.html">Solitaire 500</a>.
My entry to the contest shamefully crashed and burn at the starting line,
but
I still managed to squeeze a t-shirt and a love of the language out of
the experience. To this day, I still have both (although one is pretty much
due for replacement).</p><p> <b>I kept using Perl because</b> it is so much damn fun. Most other
languages are like station wagon cars. They get you from A to B, but
they are not much to write home about. But Perl...
Perl is like James Bond's car. Beside the driving wheel, you
have a red button here to activate the flamethrowers. Below
the glove compartment -- yes, you see right -- there's a lever
that engages the retro-propellers. And it doesn't end there:
if one was to ever
get bored with all those nifty toys, Q still comes up regularly with
new features.</p><p> <b>
I can't stop thinking about Perl
</b> for the same reason a rock star can't stop thinking about his
Fender Stratocaster XII. </p><p> <b>I'm still using Perl because</b> I have yet to find another
language that is so delightfully idiosyncratic and yet so practical.
Or
that has such a striving community. Or that has anything remotely
comparable to
that magnificent temple dedicated to Aergia that we call CPAN.</p><p> <b>I get other people to use Perl by</b> asking them what task they want
to achieve, and doing it before their eyes in a handful of lines. Once I have
thus acquired their awestruck attention, I reel them in for my
weekly Perl Lunch'n'Learns where the true corruption can begin. </p><p> <b>
I also program in </b> TCL <b> and </b>Javascript<b>, but I like Perl better since
</b> it doesn't make me want to drive red-hot tetanus-laden nails through my
prosencephalon. Javascript is not that bad, mind you -- I actually like
it. But nothing, <i>nothing</i>, can shear such deep gouges in one's psyche
like badly written TCL can. And this is coming from someone who known
Intercal, brainf*ck and VisualBasic...
</p>Yanick2008-05-11T16:03:22+00:00journalCPAN/Ohloh mashup
http://use.perl.org/~Yanick/journal/36234?from=rss
<p>
Now that I've registered my Perl modules on
<a href="http://www.ohloh.net/">Ohloh</a>,
I thought it'd be fun to make things bilateral
and have one of the <a href="http://www.ohloh.net/projects/test-pod-snippets/widgets">Ohloh widgets</a>
displayed on the
modules' CPAN page. So I mustered my <a href="http://www.greasespot.net/">Grease</a>-Fu, and
hacked
<a href="http://userscripts.org/scripts/show/25525">a little something</a>.
</p><p>
With that little script installed, if a module dist is registered
on Ohloh [*], its widget will appear on the right side of
the CPAN page right below the gravatar picture.
</p><p>
For sample modules, have a gander at
<a href="http://search.cpan.org/~yanick/Test-Pod-Snippets-0.02/">
Test::Pod::Snippet</a> or
<a href="http://search.cpan.org/~yanick/XML-XPathScript">XML::XPathScript</a>.
</p><p>
<b>[*]</b> The project must also be configured to have a
<a href="http://www.ohloh.net/announcements/human_project_urls">name url</a>
corresponding to module's name in lowercase and with all '::'
substitued by '-' (e.g., 'Test::Pod::Snippets' => 'test-pod-snippets').
</p>Yanick2008-04-23T23:50:53+00:00journalper(l)version
http://use.perl.org/~Yanick/journal/35940?from=rss
<p>
Updating the version number is all the files of a module
distribution is a pain in the behind. It's repetitive,
boring and ridiculously prone to errors -- in short, a task
fit for a script, not for humans. So I decided to hack myself
a little something, for the time being called <i>perversion</i>,
to take care of it. </p><p>
The idea is pretty straight-forward. In the root directory of my
distribution, I have a config file named <i>perversionrc</i>
that contains Perl code that return an hash of all files
where the the module version is given, and regular expressions
to capture the said version. For example, here's the
<i>perversionrc</i> of WWW::Ohloh::API:</p><blockquote><div><p> <tt>use File::Find::Rule;<br> <br>my %file;<br> <br>$file{README} = qr/WWW-Ohloh-API version (\S+)/;<br> <br>for my $m ( File::Find::Rule->file->name( '*.pm' )->in( 'lib' ) ) {<br> $file{$m} = [ qr/\$VERSION\s*=\s*'(.*?)';/,<br> qr/This document describes \S+ version (\S*)/ ];<br>}<br> <br>%file;</tt></p></div> </blockquote><p>
Once that file is present, <i>perversion</i> is ready to rock. You want to
verify that the version number is consistent in all given files?</p><blockquote><div><p> <tt>$ perversion<br>distribution version is set to 0.0.9<br>lib/WWW/Ohloh/API/Enlistment.pm:12: 0.0.6<br>!!! does not match distribution version (0.0.9) !!!<br>lib/WWW/Ohloh/API/Repository.pm:10: 0.0.6<br>!!! does not match distribution version (0.0.9) !!!<br>lib/WWW/Ohloh/API/ContributorLanguageFact.pm:10: 0.0.6<br>!!! does not match distribution version (0.0.9) !!!<br>lib/WWW/Ohloh/API/ContributorFact.pm:10: 0.0.6<br>!!! does not match distribution version (0.0.9) !!!<br>lib/WWW/Ohloh/API/ContributorFact.pm:241: 0.0.6<br>!!! does not match distribution version (0.0.9) !!!</tt></p></div> </blockquote><p>Want to set the version to a specific value?</p><blockquote><div><p> <tt>$ perversion -set 1.2.3<br>changing all versions to 1.2.3..<br> updating lib/WWW/Ohloh/API.pm..<br> updating lib/WWW/Ohloh/API/Language.pm..<br> updating lib/WWW/Ohloh/API/ActivityFacts.pm..<br> updating lib/WWW/Ohloh/API/Account.pm..<br> updating lib/WWW/Ohloh/API/Kudos.pm..<br> updating lib/WWW/Ohloh/API/Project.pm..<br> updating lib/WWW/Ohloh/API/Enlistment.pm..<br> updating lib/WWW/Ohloh/API/KudoScore.pm..<br> updating lib/WWW/Ohloh/API/Factoid.pm..<br> updating lib/WWW/Ohloh/API/Repository.pm..<br> updating lib/WWW/Ohloh/API/Projects.pm..<br> updating lib/WWW/Ohloh/API/ContributorLanguageFact.pm..<br> updating lib/WWW/Ohloh/API/Languages.pm..<br> updating lib/WWW/Ohloh/API/ActivityFact.pm..<br> updating lib/WWW/Ohloh/API/ContributorFact.pm..<br> updating lib/WWW/Ohloh/API/Analysis.pm..<br> updating lib/WWW/Ohloh/API/Kudo.pm..<br> updating README..<br>done</tt></p></div> </blockquote><p>Don't want to go through the mental challenge of computing the
next version yourself? No problem!</p><blockquote><div><p> <tt>$ perversion -inc revision<br>distribution version is set to 1.2.3<br>new distribution version is 1.2.4<br> <br>$ perversion -inc minor<br>distribution version is set to 1.2.4<br>new distribution version is 1.3.0<br> <br>$ perversion -inc major<br>distribution version is set to 1.3.0<br>new distribution version is 2.0.0<br> <br>$ perversion -inc alpha<br>distribution version is set to 2.0.0<br>new distribution version is 2.0_1</tt></p></div> </blockquote><p>
The script is still raw and in need of polishing,
but for those interested, it's available from its
very own <a href="http://babyl.dyndns.org/git/?p=perversion.git">
git repository</a>.
</p>Yanick2008-03-20T02:13:22+00:00journalXPathScript slides
http://use.perl.org/~Yanick/journal/35815?from=rss
<p>An introduction to <a href="http://search.cpan.org/~yanick/XML-XPathScript/">XPathScript</a> that I gave
at this month's Ottawa Mongers Meeting can
be found <a href="http://babyl.dyndns.org/perl/xpathscript/slides/">here</a>. </p><p>It probably reads a wee bit cryptic
without my running commentaries, but some might still enjoy it.<nobr> <wbr></nobr>:-)
</p>Yanick2008-03-02T03:43:29+00:00journalThinking about taking over NetPacket
http://use.perl.org/~Yanick/journal/35641?from=rss
<p>
At $work, an application that I wrote (<i>remora</i>, a companion
application to <a href="http://www.wireshark.org/">Wireshark</a>)
is extensively using
<a href="http://search.cpan.org/~atrak/NetPacket-0.04/">NetPacket</a>.
NetPacket is very handy but, alas, has
<a href="http://rt.cpan.org/Ticket/Display.html?id=7010">some</a>
<a href="http://rt.cpan.org/Ticket/Display.html?id=18941">bugs</a>,
and seem to be orphaned (the latest update
is from 2003). I've tried to poke the maintainers, but
Stephanie Wehner's email is no longer working, and Tim Potter didn't
reply yet (although, to be fair, I only began to poke last week).
</p><p>
Bottom line, I'm playing with the idea of taking over the module so that
I can churn a new version with the bug fixes. So if
anyone out there is in contact with Stephanie or Tim, can you let
them know a madman is nefariously organizing a coup? Thanks.<nobr> <wbr></nobr>:-)
</p>Yanick2008-02-12T17:24:22+00:00journalGit's the nightclub, Perltidy's the bouncer
http://use.perl.org/~Yanick/journal/35626?from=rss
<p>
I finally wrapped my CVS-encrusted mind
around Git's hooks. Huzzah! The biggest hurdle, really, was
realizing that there is no spoon. </p><p>
Anyway, as I'm an unsalvageable slob who always
forget to run perltidy before committing changes, I've
written a <code>pre-commit</code> hook that makes sure that
all Perl files to be committed are all clean, neat and tidy
(and aborts the commit and chides me if they are not):</p><blockquote><div><p> <tt>#!/usr/bin/perl<br> <br>use Perl6::Slurp;<br> <br>my $status = slurp '-|', 'git-status';<br> <br># only want what is going to be commited<br>$status =~ s/Changed but not updated.*$//s;<br> <br>my @dirty =<br> grep { !file_is_tidy($_) } # not tidy<br> grep {<nobr> <wbr></nobr>/\.(pl|pod|pm|t)$/ } # perl file<br> map {<nobr> <wbr></nobr>/(?:modified|new file):\s+(\S+)/ } # to be commited<br> split "\n", $status;<br> <br>exit 0 unless @dirty; # Alles gut<br> <br>warn "following files are not tidy, aborting commit\n",<br> map "\t$_\n" => @dirty;<br> <br>exit 1;<br> <br>### utility functions ###############################################<br> <br>sub file_is_tidy {<br> my $file = shift;<br> <br> my $original = slurp $file;<br> my $tidied = slurp '-|', 'perltidy', $file, '-st';<br> <br> return $original eq $tidied;<br>}</tt></p></div> </blockquote>Yanick2008-02-09T22:18:41+00:00journalGreasemonkeying dependencies
http://use.perl.org/~Yanick/journal/35507?from=rss
<p>Escalation wars... you just have to love'em.</p><p>First, David
came up with the über-cool <a href="http://cpandeps.cantrell.org.uk/">
CPAN deps</a> page.</p><p>Then <a href="http://use.perl.org/~AndyArmstrong/journal/">Andy</a>
comes up with a <a href="http://use.perl.org/article.pl?sid=07/12/15/1931244">nifty Greasemonkey script </a>
to add it to the CPAN distributions main pages. </p><p>Then I add a small patch to the script to retrieve
some information from the Deps page.</p><p>Then David creates an xml interface to CPAN deps, opening the
door wide open for Web 2.0 goodiness.</p><p>Then (and this is where we are right now) I hack together a new <a href="http://userscripts.org/scripts/show/21779">CPAN_Dependencies</a> monkeyscript
to take advantage of said xml interface.</p><p>This, of course, is nowhere near the end of the story.
My new script only scratches the surface of what can be done with the
information contained in the xml. As soon as I have some tuits,
I'll probably add a way to toggle between showing only the first-level
dependencies and all dependencies, and have dependencies color-coded
by degree of b0rkage, and whatever bell or whistle I can think of in
the meantime.</p>Yanick2008-01-29T01:28:11+00:00journalRedux
http://use.perl.org/~Yanick/journal/35000?from=rss
<p>
Lately, I've been having fun with
<a href="https://addons.mozilla.org/en-US/firefox/addon/748">GreaseMonkey</a>.
Net result: I've
re-implemented my Perl-themed friends/foes icons
(originally
<a href="http://use.perl.org/~Yanick/journal/30746">done</a>
using <a href="http://userstyles.org/stylish/">Stylish</a>)
and hacked RT to provide sorting of bugs by
severity (I got the idea for that one from
<a href="http://use.perl.org/~schwern/journal/34967">Schwern</a>'s journal). Both
monkey scripts are available on
<a href="http://userscripts.org/users/38422/scripts">userscript.org</a>.
</p><p>Also, a new version of <a href="http://cpanratings.perl.org/dist/Pod-Manual">Pod::Manual</a> is out.
The code to generate my unexpectedly wildly popular ad-hoc
<a href="http://use.perl.org/~Yanick/journal/33028">Catalyst manual</a> was already included in
the previous distributions, and in this one I added a similar
manual for <a href="http://search.cpan.org/~jsiracusa/Rose-DB-Object/">Rose::DB::Object</a>.
The order in which the modules are given is a little rough and
need improvement, but it's a start. For those who care more
about the end than the means, the pdf of both manuals
are available <a href="http://babyl.dyndns.org/perl/pod-manual">here</a> </p><p>.
</p>Yanick2007-11-29T01:23:10+00:00journalNo-one expected the Technorati inquisition
http://use.perl.org/~Yanick/journal/33947?from=rss
<p> <b>Slightly amusing trivia:</b>
before the hoola-baloo of the last few days, I was
persuaded that it was the techno<i>c</i>rati, and
that it was secret organization of nefarious hackers --
an amalgam of the <a href="http://en.wikipedia.org/wiki/Illuminati">Illuminati</a>
and WhiteWolf's <a href="http://en.wikipedia.org/wiki/Technocracy_(Mage:_The_Ascension)">Technocracy</a>.
</p><p>Anyway, here goes: <a href="http://technorati.com/claim/x2kvkhe4q">Technorati Profile</a>.</p>Yanick2007-08-01T12:21:59+00:00journalTrying to define badness: Shakesphackers
http://use.perl.org/~Yanick/journal/33858?from=rss
<p> <b>Shakesphacker</b>: (<i>n.</i>) a programer who, at the instar of Shakespeare's infamous chimps,
randomly bang on the keyboard until the laws of probability make him
generate a working line of code.</p><p>
I came up with that term Friday to try to put a label on a coding philosophy I
observed.
I'm not entierely satisfied by it though -- it sounds way too
sophisticated for the kind of feeling it try to convey. "Foo flinger"
could be more adequate.
</p><p>In all cases, shakesphackers can be easily identified by their exuberant love of <i>eval</i>s -- they firmly believe that, just like violence, if it doesn't solve your problems, it's because your not using enough of it. </p>Yanick2007-07-22T16:10:29+00:00journalPod::Manual
http://use.perl.org/~Yanick/journal/33807?from=rss
<p>A while ago, <a href="http://use.perl.org/~Yanick/journal/33028">I hacked together a way to
gather many pod files into a single pdf file</a>.
Well, finally I got around
cleaning up the code and released it as
<a href="http://search.cpan.org/~yanick/Pod-Manual/">Pod::Manual</a>.</p><p>
It's still very muchly alpha quality, but the basics seem to work.
For example, the following works (at least on my machine)[<a href="%23footnote">*]:</a> </p><blockquote><div><p> <tt>use Pod::Manual;<br> <br>my $manual = Pod::Manual->new({ title => 'Catalyst' });<br> <br>$manual->add_chapter( $_ ) for qw/<br> Catalyst::Manual::About<br> Catalyst::Manual::Actions<br> Catalyst::Manual::Cookbook<br> Catalyst::Manual::DevelopmentProcess<br> Catalyst::Manual::Internals<br> Catalyst::Manual::Intro<br> Catalyst::Manual::Plugins<br> Catalyst::Manual::Tutorial<br> Catalyst::Manual::Tutorial::Intro<br> Catalyst::Manual::Tutorial::CatalystBasics<br> Catalyst::Manual::Tutorial::BasicCRUD<br> Catalyst::Manual::Tutorial::Authentication<br> Catalyst::Manual::Tutorial::Authorization<br> Catalyst::Manual::Tutorial::Debugging<br> Catalyst::Manual::Tutorial::Testing<br> Catalyst::Manual::Tutorial::AdvancedCRUD<br> Catalyst::Manual::Tutorial::Appendices<br> Catalyst::Manual::WritingPlugins<br>/;<br> <br>$manual->save_as_pdf( 'catalyst_manual.pdf' );</tt></p></div> </blockquote><p>At this stage of the game, bug reports and feature requests
would be very welcome. As well as suggestions for other
example manuals.</p><p>[*] caveat: for the moment you need <code>TeTeX</code> installed
to generate pdf documents. One of the items on my todo list is
to allow for other means to generate the pdf (<code>jadetex</code>,
<code>FOP</code>, etc)</p>Yanick2007-07-15T01:27:00+00:00journalpush @ISA, 'Married::Man'
http://use.perl.org/~Yanick/journal/33619?from=rss
<p>On Saturday, June the 23rd, me and my lovely lady joined APIs before
friends, families and the Great Whitely-Bearded Hacker in the Sky
(He was even kind
enough to schedule some wicked light effects for the event).
</p><p>
Funnily enough, both the bride and the groom were wearing pearls
for the occasion (in my case, it was an heirloom tie-pin given by
the mother-in-law). As unforgivingly geeky as it is, I must
say I got a secret kick out of that. </p>Yanick2007-06-27T21:04:00+00:00journalCatalyst's manual
http://use.perl.org/~Yanick/journal/33028?from=rss
<p>Don't get me wrong, I love perldoc. But for documentation that span
several manpages, I often catch myself dreaming of tables of content,
indexes, real dead-tree margins on which to annotate stuff. I'm funny that
way.</p><p>So I went back to the script that I wrote to create the <a href="http://use.perl.org/~Yanick/journal/30715">XPathScript manual</a>
and tinkered a bit with it. I then used that newly-concocted black
magick (which basically convert and agglomerate pods into a docbook, which
is then LaTeXified and subsequently pdfed) to turn the
<a href="http://search.cpan.org/~jrockway/Catalyst-Manual-5.700501/">Catalyst
manual</a> into a cute little <a href="http://babyl.dyndns.org/misc/catalyst_manual.pdf">pdf</a>.
Me likes. I think I'll tidy up the aforementioned script and
publish it as Pod::Manual or something of the kin as soon as time (ah!)
allows.</p><p>(and yeah, I'm in the process of getting
my feet wet with Catalyst. Last week I was hopelessly Not Getting It, but
sometime during last week-end, an angel came to me and bapped me over the
head with its trumpet. Epiphany! I grok it, now! Even better: I think I'm digging it too!)</p>Yanick2007-04-19T02:41:58+00:00journalMeeting Availability Dialect
http://use.perl.org/~Yanick/journal/32641?from=rss
<p><b>Background</b></p><p>Organizing the March meeting of <a href="ottawa.pm.org">Ottawa.pm</a>, I came across the problem that setting a date is pretty much like playing Battleship. If a specific date is proposed, people tend respond with boolean answers (can/can't come on that day), which is perfect to assess the punctual value of the attendency function, but quite lousy to determine its monthly optimum.</p><p>So, taking the premise that there's no simple problem that can't be solved by an overcomplex solution, I thought about a way we could all signal our availabilities for a certain month in a simple, standard and easy to parse way (for I have evil plans to hack a script to help me do the scheduling). A few bus commutes later, MADness was born.</p><p><b>Meeting Availability Dialect</b></p><p>A MAD signature line has the following syntax:</p><p>
<i>month</i> : <i>availability</i></p><p>The month is simply the name of the month. Availability is defined by a sequence of tokens that add or remove available days, depending if they are modified by a plus or minus sign.</p><p>E.g.:</p><p>
April : WD + Sat - Wed - Day(13)</p><p>which means any work day, plus Satudays, but not Wednesdays or the 13th of the month.</p><p>The base token are:</p><p>Mon<br>Tue<br>Wed<br>Thu<br>Fri<br>Sat<br>Sun<br>AD - Any day<br>WE - Week-end (same as 'Sat + Sun')<br>WD - Week days (same as 'Mon + Tue + Wed + Thu + Fri')</p><p>For a specific date, use Day(X), where X is the date. For example, 'WD - Day(14)' means all week days, except on the 14th (one can surmise that was for February).</p><p>To target a specific week, append '(X)' to the token, where X is the week in question. Several weeks can be given, separated by commas or a range operator '..'. For example, 'Tue - Tue(2)' is equivalent to 'Tue(1,3..4)' and means the first, third or fourth Tuesday of the month.</p><p>Availability is resolved from left to right, which means that, for example,</p><p>
April : AD - WE + Sun(1)</p><p>means any day, except week-ends, although the first Sunday is okay. Note that<br>this is equivalent to</p><p>
April: WD + Sun(1)</p><p>MAD doesn't consider whitespaces as significant. The full availability, however, must be represented on a single line.</p>Yanick2007-03-10T18:00:13+00:00journal$tea="Earl Grey";print $tea
http://use.perl.org/~Yanick/journal/32417?from=rss
<p>Don't go and gnaw off your fingers just yet. Judging from this demonstration of the
<a href="http://www.youtube.com/watch?v=KyLqUf4cdwc">bleeding edge of speech recognition technology</a>, we will need our ten stubby friends to bang on keyboards for a little while still....</p>Yanick2007-02-16T03:09:06+00:00journalXML::XPathScript 1.47 is out
http://use.perl.org/~Yanick/journal/32217?from=rss
<p>It is with great relish that I announce that XML::XPathScript v1.47 is on its way to a CPAN mirror near you.</p><p>[ ED: Do'h! The test that was supposed to gracefully skip if B::XPath isn't installed bombs instead. (blame it on my naive assumption that 'eval { use B::XPath; 1 }' would work). I'll do a s/use/require/ on that test and release 1.48 tonight. ]</p><p>What is new in this release:</p><p>* template tag attributes can now be functions as well as strings.</p><p>
For example,</p><p>
$template->set( 'foo' => { testcode => sub {<br>
my( $n, $t ) = @_;<br>
my $name = $n->findvalue( 'name()' );<br>
$t->set({ pre => transfurbicate( $name ) });<br>
return $DO_SELF_AND_CHILDREN;<br>
}<br>
} );</p><p>
can now be written</p><p>
$template->set( 'foo' => { pre => sub {<br>
my( $n, $t ) = @_;<br>
my $name = $n->findvalue( 'name()' );<br>
return transfurbicate( $name );<br>
}<br>
} );</p><p>* The 'content' template attribute, which associates template elements to<br>mini-stylesheets.</p><p>
E.g., the code</p><p>
<%<br>
$template->set( 'foo' => {<br>
pre => '<newFoo foo_myattr="{@myattr}" >',<br>
post => '</newFoo>',<br>
action => 'bar', # only process 'bar' node children<br>
} );<br>
%></p><p>
can now be written</p><p>
<%<br>
$template->set( 'foo' => { content => <<'END_CONTENT' } );<br>
<newFoo foo_myattr="{@myattr}" > <%# look Ma, we interpolate! %><br>
<%~ bar %> <%# only process bar children %><br>
</newFoo><br>
END_CONTENT<br>
%><br>
<%# process all foo's %><br>
<%~<nobr> <wbr></nobr>//foo %></p><p>
Or, to be more easy on the eye, we can use the short-hand version:</p><p>
<%@ foo<br>
<newFoo foo_myattr="{@myattr}" > <%# look Ma, we interpolate! %><br>
<%~ bar %> <%# only proces bar children %><br>
</newFoo><br>
%><br>
<%# process all foo's %><br>
<%~<nobr> <wbr></nobr>//foo %></p><p>* B::XPath now a supported DOM tree. Bored with transforming XML documents?<br>How about transforming Perl Optrees?<nobr> <wbr></nobr>:-)</p><p>
use B::XPath;<br>
use XML::XPathScript;</p><p>
sub guinea_pig {<br>
my $x = shift;<br>
print "oink oink " x $x;<br>
}</p><p>
my $xps = XML::XPathScript->new;</p><p>
$xps->set_dom( B::XPath->fetch_root( \&guinea_pig ) );<br>
$xps->set_stylesheet( '<%~<nobr> <wbr></nobr>//print %>' );</p><p>
print $xps->transform;</p>Yanick2007-01-20T23:46:12+00:00journalResurrecting Ottawa.pm
http://use.perl.org/~Yanick/journal/32125?from=rss
<p>One of my resolutions for the new year is to try and
see if I can stir Ottawa.pm back to life (it kinda went
under two year-ish ago). I've already sent a humble request
to the Power that Is at pm.org to get the keys to
the ottawa.pm.org website and mailing list. But still remains
the most daunting task: gather minions. I already spotted 11
Perl programmers on meetup.com that would probably be interested.
And I should also be visiting the local LUG, always a fertile ground
for young llamas....
</p><p>
Anyway. No need to say, if you are in the vicinity and want to join
the fray, please feel free to frantically wave in my direction.
If not, well, wish me luck.<nobr> <wbr></nobr>:-)</p>Yanick2007-01-12T03:26:20+00:00journal