<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Planet Perl Iron Man</title>
  <link rel="alternate" href="http://ironman.enlightenedperl.org/" type="text/html"/>
  <updated>0</updated>
  <generator>Plagger/0.7.17</generator>
  <subtitle>Perl Iron Man Competition</subtitle>
  <id>tag:ironman.enlightenedperl.org,2006:smartfeed:all</id>
  <entry>
    <title>location location location</title>
    <link rel="alternate" href="http://eatenbyagrue.org/location_location_location.html" type="text/html"/>
    <summary type="text">My laptop has had an interesting couple of days. The main filesystem went
read-only a couple of nights ago after a couple of random journal errors.
After being fsck'd and cleaned up it did it again, so I reinstalled it
and restored it from backup yesterday. Then last night it overheated,
leading me to open the case and clean the wall of dust out of the fan.
Its back together now, but a couple of lost of tiny parts means I have no
indicator lights and no trackpoint. Fortunately the trackpad still works,
but its taking a little getting used to. On the other hand, its not
burning my lap or my hands anymore, so its probably an overall victory
though its not quite feeling that way yet.

One of the things I did lose in the rebuild, due to it not living in one
of my backup locations (which is /etc/ and /home/rob) is my cute little
mobile roaming script. I rewrote it on the bus on the way home yesterday
and thought that perhaps its interesting enough to post here.

The basic idea is that every day I switch between at least two networks.
My home network has a PC in the hall cupboard which among other things
runs a web proxy and a mail server. Its also the firewall, so web and
mail traffic can't go out directly. Work on the other hand, implements
transparent proxying (with some network authentication) and has a SMTP
server, but naturally it has a different address. I also occassionally
use other networks (friend's places, coffee shops, etc) which usually
have no facilities at all, requiring me to fend for myself.

My laptop runs a SMTP server (Postfix) of course, because that's just
what you do on Unix. I also run a Squid proxy which I point all my local
HTTP clients at. This way, when I move networks, I only have to
reconfigure the local proxy rather than tweak every web client I have.

I spent a long time looking for a decent roaming reconfiguration package,
but I never managed to find one. Some would try to do network detection
and too often get it wrong. Some would have overly complicated and/or
feature deficient configuration languages. I vaguely recall that I really
liked one of them but it was tightly integrated with NetworkManager,
which I don't use because it could never seem to keep the network alive
for more than a few minutes (and it appears to be pretty much tied to the
GUI, which is painful when I need network on the console).

So, in the finest open source tradition, I rolled my own. The script
itself is trivial; its just a tiny template expander. I'll list the
script in a moment, but first I'll talk about its operation.

The script, which I call location, takes a location name on the command
line (like home or work), runs over a (hardcoded) list of config files,
reads them in, modifies them, and spits them out to the same file. It
makes modifications according to templates that may exist in the file. If
the file has no template, then location ends up emitting the unchanged
file.

In any file you want it to modify, you add an appropriate template. This
is the template I have in my /etc/postfix/main.cf:

### START-LOCATION-TEMPLATE
##@ home relayhost = lookout.home
##@ work relayhost = smtp.monash.edu.au
##! /etc/init.d/postfix restart
##! sleep 1
##! /usr/bin/mailq -q
### END-LOCATION-TEMPLATE

When it finds itself inside a template, location stops its normal
operation of outputting the lines of the file as-is and instead starts
parsing. Interesting lines begin with ##, anything else is ignored. Its
the third character that determines how the line is interpreted. So far I
have the following functions:

  * #: do nothing, just output the line

  * @: emit if at location. If the location specified on the command line
    matches the first argument to @, then the rest of the line is added
    to the file as-is.

  * !: run command. Calls a shell to run the specified command after the
    file has been generated.

  * &gt;: interpolate line. Include the rest of the line in the file, but
    expand any %variable%-type markers. So far only %location% is
    defined, and is replaced with the location specified on the command
    line.

(I'll provide an example of that last one in a moment).

So in the case of main.cf, lets say we ran location with home as the
location. This would result in the template section being written to the
output file as:

### START-LOCATION-TEMPLATE
##@ home relayhost = lookout.home
relayhost = lookout.home
##@ work relayhost = smtp.monash.edu.au
##! /etc/init.d/postfix restart
##! sleep 1
##! /usr/bin/mailq -q
### END-LOCATION-TEMPLATE

The listed commands are then run, which cause Postfix to be restarted and
the mail queue to be flushed:

/etc/init.d/postfix restart
sleep 1
/usr/bin/mailq -q

Naturally Postfix interprets the template parts of the file as comments,
so nothing to worry about. The next time location is run, the "bare"
relayhost line is ignored, so it doesn't get in the way.

The config for Squid is similar. Because Squid's config file is huge, I
don't quite trust my script to handle the whole thing sanely, so at the
bottom of squid.conf I've added:

include /etc/squid/location.conf

And in location.conf I have:

### START-LOCATION-TEMPLATE
##@ home cache_peer lookout.home parent 8080 0 default
##@ home never_direct allow all
##! /etc/init.d/squid restart
### END-LOCATION-TEMPLATE

By default Squid will try and hit the internet directly, which is fine
for work and unknown locations. For home, i need to force it to always go
to an upstream proxy, which is what those the cache_peer and never_direct
directives will achieve.

The proxy at work used to be an authenticating proxy, so I had to specify
both a peer and a username/password combination. This made the required
amount of variable config a little unwieldy to be include in a template,
which is where the &gt; function came from. location.conf used to have this:

##&gt; include /etc/squid/upstream.%location%.conf

Which would arrange for upstream.home.conf, upstream.work.conf, etc to be
included depending on the location. There's every chance this will come
in useful again one day, so I've left the code in there for now.

Here's the script in its entirety:

#!/usr/bin/env perl

use 5.010;

use warnings;
use strict;

my @files = qw(
    /etc/squid/location.conf
    /etc/postfix/main.cf
);

use autodie qw(:default exec);

use FindBin;

if ($&lt; != 0) {
    exec "/usr/bin/sudo", "$FindBin::Bin/$FindBin::Script", @ARGV;
}

say "usage: location &lt;where&gt;" and exit 1 if @ARGV != 1;

my ($location) = @ARGV;

for my $file (@files) {
    say "building: $file";

    my @out;
    my @cmd;

    open my $in, "&lt;", $file;

    my $in_template = 0;
    while (my $line = &lt;$in&gt;) {
        chomp $line;

        if ($line =~ m/^### START-LOCATION-TEMPLATE/) {
            $in_template = 1;
            push @out, $line;
            next;
        }

        if ($line =~ m/^### END-LOCATION-TEMPLATE/) {
            $in_template = 0;
            push @out, $line;
            next;
        }

        if (!$in_template) {
            push @out, $line;
            next;
        }

        my ($tag) = $line =~ m/^##([#@!&gt;])/;
        if (!$tag) {
            next;
        }

        given ($tag) {
            when ('#') {
                push @out, $line;
                next;
            }

            when ('@') {
                push @out, $line;

                my ($want, $rest) = $line =~ m/^##@ (\w+) (.*)/;
                if ($want eq $location) {
                    push @out, $rest;
                }

                next;
            }

            when ('!') {
                push @out, $line;

                my ($cmd) = $line =~ m/^##! (.*)/;
                push @cmd, $cmd;

                next;
            }

            when ('&gt;') {
                push @out, $line;

                my ($rest) = $line =~ m/^##&gt; (.*)/;

                $rest =~ s/%location%/$location/g;

                push @out, $rest;
            }
        }
    }

    die "$file: unclosed location template" if $in_template;

    close $in;

    open my $out, "&gt;", $file;
    say $out $_ for @out;
    close $out;

    for my $cmd (@cmd) {
        say "running: $cmd";
        system $cmd;
    }
}

Because its so trivial and I only run it a couple of times a day, I just
run it when I get to work (location work) or when I get home (location
home). If I felt inclined I could probably hook it up to my network stuff
but I think that would be more trouble than its worth.

On occassion I have to use Windows on the same machine. I have no idea
how to achieve something similar there, so I just reconfigure my browser.
Fortunately I don't go there often, and almost never from work. This is
why I like open source. I can make my system work in exactly the way I
want and usually with a minimum of fuss.</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>My laptop has had an interesting couple of days. The main filesystem went
read-only a couple of nights ago after a couple of random journal errors.
After being <code>fsck</code>'d and cleaned up it did it again, so I reinstalled it and
restored it from backup yesterday. Then last night it overheated, leading me
to open the case and clean the wall of dust out of the fan. Its back together
now, but a couple of lost of tiny parts means I have no indicator lights and
no trackpoint. Fortunately the trackpad still works, but its taking a little
getting used to. On the other hand, its not burning my lap or my hands
anymore, so its probably an overall victory though its not quite feeling that
way yet.</p>

<p>One of the things I did lose in the rebuild, due to it not living in one of my
backup locations (which is <code>/etc/</code> and <code>/home/rob</code>) is my cute little mobile
roaming script. I rewrote it on the bus on the way home yesterday and thought
that perhaps its interesting enough to post here.</p>

<p>The basic idea is that every day I switch between at least two networks. My
home network has a PC in the hall cupboard which among other things runs a web
proxy and a mail server. Its also the firewall, so web and mail traffic can't
go out directly. Work on the other hand, implements transparent proxying (with
some network authentication) and has a SMTP server, but naturally it has a
different address. I also occassionally use other networks (friend's places,
coffee shops, etc) which usually have no facilities at all, requiring me to
fend for myself.</p>

<p>My laptop runs a SMTP server (Postfix) of course, because that's just what you
do on Unix. I also run a Squid proxy which I point all my local HTTP clients
at. This way, when I move networks, I only have to reconfigure the local proxy
rather than tweak every web client I have.</p>

<p>I spent a long time looking for a decent roaming reconfiguration package, but
I never managed to find one. Some would try to do network detection and too
often get it wrong. Some would have overly complicated and/or feature
deficient configuration languages. I vaguely recall that I really liked one of
them but it was tightly integrated with NetworkManager, which I don't use
because it could never seem to keep the network alive for more than a few
minutes (and it appears to be pretty much tied to the GUI, which is painful
when I need network on the console).</p>

<p>So, in the finest open source tradition, I rolled my own. The script itself is
trivial; its just a tiny template expander. I'll list the script in a moment,
but first I'll talk about its operation.</p>

<p>The script, which I call <code>location</code>, takes a location name on the command line
(like <code>home</code> or <code>work</code>), runs over a (hardcoded) list of config files, reads
them in, modifies them, and spits them out to the same file. It makes
modifications according to templates that may exist in the file. If the file
has no template, then <code>location</code> ends up emitting the unchanged file.</p>

<p>In any file you want it to modify, you add an appropriate template. This is
the template I have in my <code>/etc/postfix/main.cf</code>:</p>

<pre><code>### START-LOCATION-TEMPLATE
##@ home relayhost = lookout.home
##@ work relayhost = smtp.monash.edu.au
##! /etc/init.d/postfix restart
##! sleep 1
##! /usr/bin/mailq -q
### END-LOCATION-TEMPLATE
</code></pre>

<p>When it finds itself inside a template, <code>location</code> stops its normal operation
of outputting the lines of the file as-is and instead starts parsing.
Interesting lines begin with <code>##</code>, anything else is ignored. Its the third
character that determines how the line is interpreted. So far I have the
following functions:</p>

<ul>
<li><code>#</code>: do nothing, just output the line</li>
<li><code>@</code>: emit if at location. If the location specified on the command line matches the first argument to <code>@</code>, then the rest of the line is added to the file as-is.</li>
<li><code>!</code>: run command. Calls a shell to run the specified command after the file has been generated.</li>
<li><code>&gt;</code>: interpolate line. Include the rest of the line in the file, but expand any <code>%variable%</code>-type markers. So far only <code>%location%</code> is defined, and is replaced with the location specified on the command line.</li>
</ul>

<p>(I'll provide an example of that last one in a moment).</p>

<p>So in the case of <code>main.cf</code>, lets say we ran <code>location</code> with <code>home</code> as the
location. This would result in the template section being written to the
output file as:</p>

<pre><code>### START-LOCATION-TEMPLATE
##@ home relayhost = lookout.home
relayhost = lookout.home
##@ work relayhost = smtp.monash.edu.au
##! /etc/init.d/postfix restart
##! sleep 1
##! /usr/bin/mailq -q
### END-LOCATION-TEMPLATE
</code></pre>

<p>The listed commands are then run, which cause Postfix to be restarted and the
mail queue to be flushed:</p>

<pre><code>/etc/init.d/postfix restart
sleep 1
/usr/bin/mailq -q
</code></pre>

<p>Naturally Postfix interprets the template parts of the file as comments, so
nothing to worry about. The next time <code>location</code> is run, the "bare"
<code>relayhost</code> line is ignored, so it doesn't get in the way.</p>

<p>The config for Squid is similar. Because Squid's config file is huge, I don't
quite trust my script to handle the whole thing sanely, so at the bottom of
<code>squid.conf</code> I've added:</p>

<pre><code>include /etc/squid/location.conf
</code></pre>

<p>And in <code>location.conf</code> I have:</p>

<pre><code>### START-LOCATION-TEMPLATE
##@ home cache_peer lookout.home parent 8080 0 default
##@ home never_direct allow all
##! /etc/init.d/squid restart
### END-LOCATION-TEMPLATE
</code></pre>

<p>By default Squid will try and hit the internet directly, which is fine for
work and unknown locations. For home, i need to force it to always go to an
upstream proxy, which is what those the <code>cache_peer</code> and <code>never_direct</code>
directives will achieve.</p>

<p>The proxy at work used to be an authenticating proxy, so I had to specify both
a peer and a username/password combination. This made the required amount of
variable config a little unwieldy to be include in a template, which is where
the <code>&gt;</code> function came from. <code>location.conf</code> used to have this:</p>

<pre><code>##&gt; include /etc/squid/upstream.%location%.conf
</code></pre>

<p>Which would arrange for <code>upstream.home.conf</code>, <code>upstream.work.conf</code>, etc to be
included depending on the location. There's every chance this will come in
useful again one day, so I've left the code in there for now.</p>

<p>Here's the script in its entirety:</p>

<pre><code>#!/usr/bin/env perl

use 5.010;

use warnings;
use strict;

my @files = qw(
    /etc/squid/location.conf
    /etc/postfix/main.cf
);

use autodie qw(:default exec);

use FindBin;

if ($&lt; != 0) {
    exec "/usr/bin/sudo", "$FindBin::Bin/$FindBin::Script", @ARGV;
}

say "usage: location &lt;where&gt;" and exit 1 if @ARGV != 1;

my ($location) = @ARGV;

for my $file (@files) {
    say "building: $file";

    my @out;
    my @cmd;

    open my $in, "&lt;", $file;

    my $in_template = 0;
    while (my $line = &lt;$in&gt;) {
        chomp $line;

        if ($line =~ m/^### START-LOCATION-TEMPLATE/) {
            $in_template = 1;
            push @out, $line;
            next;
        }

        if ($line =~ m/^### END-LOCATION-TEMPLATE/) {
            $in_template = 0;
            push @out, $line;
            next;
        }

        if (!$in_template) {
            push @out, $line;
            next;
        }

        my ($tag) = $line =~ m/^##([#@!&gt;])/;
        if (!$tag) {
            next;
        }

        given ($tag) {
            when ('#') {
                push @out, $line;
                next;
            }

            when ('@') {
                push @out, $line;

                my ($want, $rest) = $line =~ m/^##@ (\w+) (.*)/;
                if ($want eq $location) {
                    push @out, $rest;
                }

                next;
            }

            when ('!') {
                push @out, $line;

                my ($cmd) = $line =~ m/^##! (.*)/;
                push @cmd, $cmd;

                next;
            }

            when ('&gt;') {
                push @out, $line;

                my ($rest) = $line =~ m/^##&gt; (.*)/;

                $rest =~ s/%location%/$location/g;

                push @out, $rest;
            }
        }
    }

    die "$file: unclosed location template" if $in_template;

    close $in;

    open my $out, "&gt;", $file;
    say $out $_ for @out;
    close $out;

    for my $cmd (@cmd) {
        say "running: $cmd";
        system $cmd;
    }
}
</code></pre>

<p>Because its so trivial and I only run it a couple of times a day, I just run
it when I get to work (<code>location work</code>) or when I get home (<code>location home</code>).
If I felt inclined I could probably hook it up to my network stuff but I think
that would be more trouble than its worth.</p>

<p>On occassion I have to use Windows on the same machine. I have no idea how to
achieve something similar there, so I just reconfigure my browser. Fortunately
I don't go there often, and almost never from work. This is why I like open
source. I can make my system work in exactly the way I want and usually with a
minimum of fuss.</p>
</div>
    </content>
    <category term="perl laptop"/>
    <published>2010-02-08T21:49:09Z</published>
    <updated>2010-02-08T21:49:09Z</updated>
    <author>
      <name>Robert Norris</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:eatenbyagrue.org,2010-02-08/location_location_location</id>
  </entry>
  <entry>
    <title>Template::Semantic</title>
    <link rel="alternate" href="http://onperl.ru/onperl/2010/02/templatesemantic.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Один из бешеных японцев™ — Наоки Томита — сегодня опубликовал на спане
интересный модуль Tempalte::Semantic, один из немногих yet another-шаблонизаторов,
на который стоит обратить внимание.

Сам шаблон представляет собой обычный HTML-фрагмент, а данные в него
подставляются из хеша, структура которого похожа на описание правил CSS
или путей XPath. Важно, что в HTML-код шаблона не требуется вписывать
никаких искусственных конструкций для интерполяции переменных.

Например, чтобы вывести заголовок на страницу, сначала создаем
HTML-заготовку:

<html>
<head>
<title/>
</head>
</html>

А затем описываем правила а-ля CSS:

use v5.10;
use strict;
use Template::Semantic;

say Template::Semantic-&gt;process(
'title.html',
{
'html title' =&gt; 'My Title',
}
);

Эта программа напечатает HTML-код с подставленным заголовком:

<html>
<head>
<title>My Title</title>
</head>
</html>

— Fantastique!

Описания с CSS-селекторами или XPath-адресами допустимо создавать и более
сложной структуры, в том числе с вложенными хешами и списками (последние
позволяют размножать фрагменты HTML-шаблонов).

Примеры наглядно описаны в документации модуля, а кроме того собраны в
отдельном файле Template::Semantice::Cookbook.</div>
    </summary>
    <content type="html">
        &lt;p&gt;Один из б&lt;em&gt;ешеных японцев™ — &lt;/em&gt;&lt;a href="http://e8y.net/"&gt;Наоки Томита&lt;/a&gt; —&amp;nbsp;сегодня опубликовал на спане интересный модуль &lt;a href="http://search.cpan.org/perldoc?Template::Semantic"&gt;Tempalte::Semantic&lt;/a&gt;, один из немногих &lt;em&gt;yet another-&lt;/em&gt;шаблонизаторов, на который стоит обратить внимание.&lt;/p&gt;
&lt;p&gt;Сам шаблон представляет собой обычный HTML-фрагмент, а данные в него подставляются из хеша, структура которого похожа на описание правил CSS&amp;nbsp;или путей&amp;nbsp;XPath. Важно, что в HTML-код шаблона не требуется вписывать никаких искусственных конструкций для интерполяции переменных. &lt;/p&gt;
&lt;p&gt;Например, чтобы вывести заголовок на страницу, сначала создаем HTML-заготовку:&lt;/p&gt;&lt;tt&gt;
&lt;p&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/p&gt;&lt;/tt&gt;
&lt;p&gt;А затем описываем правила а-ля CSS:&lt;/p&gt;&lt;tt&gt;
&lt;p&gt;use v5.10;&lt;br /&gt;use strict;&lt;br /&gt;use Template::Semantic;&lt;/p&gt;
&lt;p&gt;say Template::Semantic-&amp;gt;process(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'title.html',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'html title' =&amp;gt; 'My Title',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;);&lt;/p&gt;&lt;/tt&gt;
&lt;p&gt;Эта программа напечатает HTML-код с подставленным заголовком:&lt;/p&gt;&lt;tt&gt;
&lt;p&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;head&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;&lt;span&gt;My Title&lt;/span&gt;&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/p&gt;&lt;/tt&gt;
&lt;p&gt;&lt;em&gt;— &lt;acronym title="&amp;#x41E;&amp;#x445;&amp;#x443;&amp;#x435;&amp;#x43D;&amp;#x43D;&amp;#x43E;!"&gt;Fantastique!&lt;/acronym&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Описания с CSS-селекторами или XPath-адресами допустимо создавать и более сложной структуры, в том числе с вложенными хешами и списками (последние позволяют размножать фрагменты HTML-шаблонов).&lt;/p&gt;
&lt;p&gt;Примеры наглядно описаны в документации модуля, а кроме того собраны в отдельном файле &lt;a href="http://search.cpan.org/~tomita/Template-Semantic-0.01/lib/Template/Semantic/Cookbook.pod"&gt;Template::Semantice::Cookbook&lt;/a&gt;.&lt;/p&gt;
        
    </content>
    <category term="CPAN Веб perl template::semantic templating"/>
    <published>2010-02-08T20:40:19+01:00</published>
    <updated>2010-02-08T20:40:19+01:00</updated>
    <author>
      <name>ash</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:onperl.ru,2010:/onperl//1.132</id>
  </entry>
  <entry>
    <title>Forcing IE to accept script tags in innerHTML</title>
    <link rel="alternate" href="http://blogs.perl.org/users/clinton_gormley/2010/02/forcing-ie-to-accept-script-tags-in-innerhtml.html" type="text/html"/>
    <summary type="text">So, my first blog post, and instead of Perl, I'm writing about
Javascript.

I'm using a common idiom:

  * AJAX call returns HTML with embedded script tags

  * create a temporary &lt;div&gt;

  * div.innerHTML = request.responseText

  * move the children of the div to the appropriate spot

Firefox conveniently executes the script texts. Opera and Safari require
extra steps to execute the script contents (eg, globalEval in jquery),
and IE does whatever the hell it pleases.

IE usually works with globalEval, except when it doesn't. I found that if
the AJAX response was just a single script tag, then IE would filter it
out. But script tags were being created in certain circumstances.

Long story short, if you need to return a single &lt;script&gt; tag, wrap it in
a &lt;form&gt; tag. For whatever reason, IE will then accept it as innerHTML
and create the script node, which you can then execute with globalEval or
similar</summary>
    <content type="html">
        &lt;p&gt;So, my first blog post, and instead of Perl, I'm writing about Javascript.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;p&gt;I'm using a common idiom: &lt;br /&gt;
    &lt;/p&gt;&lt;ul&gt;&lt;li&gt;AJAX call returns HTML with embedded script tags&lt;/li&gt;&lt;li&gt;create a temporary &amp;lt;div&amp;gt;&lt;/li&gt;&lt;li&gt;div.innerHTML = request.responseText&lt;/li&gt;&lt;li&gt;move the children of the div to the appropriate spot&lt;/li&gt;&lt;/ul&gt;Firefox conveniently executes the script texts. Opera and Safari require extra steps to execute the script contents (eg, &lt;a href="http://api.jquery.com/jQuery.globalEval/"&gt;globalEval&lt;/a&gt; in jquery), and IE does whatever the hell it pleases.&lt;br /&gt;&lt;br /&gt;IE usually works with globalEval, except when it doesn't.&amp;nbsp; I found that if the AJAX response was just a single script tag, then IE would filter it out.&amp;nbsp; But script tags were being created in certain circumstances.&lt;br /&gt;&lt;br /&gt;Long story short, if you need to return a single &amp;lt;script&amp;gt; tag, wrap it in a &amp;lt;form&amp;gt; tag.&amp;nbsp; For whatever reason, IE will then accept it as innerHTML and create the script node, which you can then execute with globalEval or similar&lt;br /&gt;&lt;br /&gt;

        

    </content>
    <category term="javascript ie"/>
    <published>2010-02-08T17:45:26Z</published>
    <updated>2010-02-08T17:45:26Z</updated>
    <author>
      <name>Clinton Gormley</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogs.perl.org,2010:/users/clinton_gormley//239.257</id>
  </entry>
  <entry>
    <title>Dancer&amp;#8217;s development update, near to release 1.140</title>
    <link rel="alternate" href="http://www.sukria.net/fr/archives/2010/02/08/dancers-development-update/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Lots of good things happened recently in Dancer's development, here they
are:


HTTP::Server::Simple::PSGI
--------------------------

After my last post about Dancer, Tatsuiko Miyagawa suggested to build
Dancer's standalone server upon a PSGI-aware layer, rather than on
HTTP::Server::Simple::CGI.

A couple of days later, he released HTTP::Server::Simple::PSGI, which is
actually based HTTP::Server::Simple (which itself doesn't depend on any
non-core modules).

A few patches later, the standalone server was refactored and running on
this new guy. That means when writing a Dancer app, you can now always
rely on PSGI environment goodness, whereas you're using the standalone
server, or the Plack architecture. That just rocks, again kudos to
@miyagawa.


Dancer::Request
---------------

The Dancer::Request class got also heavily refactored and enhanced, it
can now provide the user with an access to the raw body of the incoming
request (thanks to RasterBurn for the report).

By the way, this class needs still so more features, and I'm actively
working on it. I may release Dancer 1.2 when I'm happy with that one.

Oh and it also now provides a complete documentation. POD FTW.


Dancer::Route
-------------

I also gave a shot at Dancer::Route, which has been recently patched to
support some new features (prefix and conditional matching, thanks to
Frank Cuny)


No more CGI.pm, really!
-----------------------

I also found that CGI.pm was still used in one very place for rendering
and HTML page. This was a shame as we wanted Dancer to be 100%
CGI.pm-free. Hence the patch that actually allow us to say it now, for
REAL ;)

All of this freash meat is available on my GitHub repo and will be soon
released to CPAN, under version 1.140. Stay tuned!</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>Lots of good things happened recently in Dancer's development, here they are:</p>
<h2><code>HTTP::Server::Simple::PSGI</code></h2>
<p>After <a href="http://www.sukria.net/fr/archives/2010/02/02/dive-into-dancers-code-core-and-extensions/">my last post</a> about <a href="http://dancer.sukria.net">Dancer</a>, <a href="http://bulknews.typepad.com/">Tatsuiko Miyagawa</a> suggested to build Dancer's standalone server upon a PSGI-aware layer, rather than on <code>HTTP::Server::Simple::CGI</code>.</p>
<p>A couple of days later, he released <a href="http://search.cpan.org/dist/HTTP-Server-Simple-PSGI/"><code>HTTP::Server::Simple::PSGI</code></a>, which is actually based <a href="http://search.cpan.org/dist/HTTP-Server-Simple/"><code>HTTP::Server::Simple</code></a> (which itself doesn't depend on any non-core modules). </p>
<p>A few patches later, the standalone server was refactored and running on this new guy. That means when writing a Dancer app, you can now always rely on PSGI environment goodness, whereas you're using the standalone server, or the Plack architecture. That just rocks, again kudos to <a href="http://twitter.com/miyagawa">@miyagawa</a>.</p>
<h2><code>Dancer::Request</code></h2>
<p>The <code>Dancer::Request</code> class got also heavily refactored and enhanced, it can now provide the user with an access to the raw body of the incoming request (thanks to <a href="http://github.com/RasterBurn">RasterBurn</a> for the report).</p>
<p>By the way, this class needs still so more features, and I'm actively working on it. I may release Dancer 1.2 when I'm happy with that one.</p>
<p>Oh and it also now provides a complete documentation. POD FTW.</p>
<h2><code>Dancer::Route</code></h2>
<p>I also <a href="http://github.com/sukria/Dancer/commit/75864032558c11f81fd7cf6fa4b094d41fddc730">gave a shot</a> at <code>Dancer::Route</code>, which has been recently patched to support some new features (prefix and conditional matching, thanks to <a href="http://lumberjaph.net/blog/">Frank Cuny</a>)</p>
<h2>No more <code>CGI.pm</code>, really!</h2>
<p>I also found that <code>CGI.pm</code> was still used in one very place for rendering and HTML page. This was a shame as we wanted Dancer to be 100% CGI.pm-free. Hence <a href="http://github.com/sukria/Dancer/commit/736cbbc00cdd3da88f4f3a29554a8f5d112d191c">the patch</a> that actually allow us to say it now, for REAL ;)</p>
<p>All of this freash meat is available on <a href="http://github.com/sukria/Dancer">my GitHub repo</a> and will be soon released to <a href="http://search.cpan.org/dist/Dancer/">CPAN</a>, under version 1.140. Stay tuned!</p>
</div>
    </content>
    <category term="Programming The Void Dancer Perl"/>
    <published>2010-02-08T18:40:52+01:00</published>
    <updated>2010-02-08T18:40:52+01:00</updated>
    <author>
      <name>sukria</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.sukria.net/fr/?p=1425</id>
  </entry>
  <entry>
    <title>Faster.pm とデバッグ</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100208/1265644668" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">FASTER_VERBOSE=2 FASTER_DEBUG=1 perl -Mblib -MFaster -e 'use IO::Socket; IO::Socket-&gt;new()'

とかやって適当にデバッグするわけだが、FASTER_VERBOSE は冗長なデバッグメッセージの表示がでるようになる。レベルに1 と 2
があることに注意。

FASTER_DEBUG=1 にすると、中間ファイルの .c が消えなくなる。</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
<pre>
FASTER_VERBOSE=2 FASTER_DEBUG=1 perl -Mblib -MFaster -e 'use IO::Socket; IO::Socket-&gt;new()'
</pre>

			<p>とかやって適当にデバッグするわけだが、FASTER_VERBOSE は冗長なデバッグメッセージの表示がでるようになる。レベルに1 と 2 があることに注意。</p>
			<p>FASTER_DEBUG=1 にすると、中間ファイルの .c が消えなくなる。</p>
		</div>
</div>
    </content>
    <published>2010-02-09T00:57:48+09:00</published>
    <updated>2010-02-09T00:57:48+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100208/1265644668</id>
  </entry>
  <entry>
    <title>[perl]Today’s assertion failure on Perl5.10.1</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100208/1265644419" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Perl5.10.1 をメインでつかっているのだが、あいかわらずすげー微妙なエッジケースにバグがある。5.8.9
よりもやはりバグを踏む可能性がちとたかい。とはいえ、すげーくさいところなので、普通の人はまず踏まないとおもうけど。

今日ふんだのはこんなの。「そんなことする方が悪い」のだが、Assertion failed で落ちるのはバグなので、perlbug っといた。

なおこれ perl5.10 だと segv するが、perl5.10.1 だと assertion failure で、perl5.8.9 だと
no problem だった。

use 5.008001;
{
    package ClassB;    sub DESTROY { }
}
{
    package ClassA;    our @ISA = qw(ClassB);
    *DESTROY = *ClassB::DESTROY;
    delete @{'ClassB::'}{"DESTROY"};

    bless *STDIN{IO}, "ClassA";
}

------------------------------------------------------------------------

Faster.pm をいじってるときに踏んだから、なんか Faster.pm
のバグだろうとおもって検討ちがいなところを調べまくって無駄に時間つかってもうた。f</div>
    </summary>
    <content type="html">
		&lt;div class="section"&gt;
			&lt;p&gt;Perl5.10.1 をメインでつかっているのだが、あいかわらずすげー微妙なエッジケースにバグがある。5.8.9 よりもやはりバグを踏む可能性がちとたかい。とはいえ、すげーくさいところなので、普通の人はまず踏まないとおもうけど。&lt;/p&gt;
			&lt;p&gt;今日ふんだのはこんなの。「そんなことする方が悪い」のだが、Assertion failed で落ちるのはバグなので、perlbug っといた。&lt;/p&gt;
			&lt;p&gt;なおこれ perl5.10 だと segv するが、perl5.10.1 だと assertion failure で、perl5.8.9 だと no problem だった。&lt;/p&gt;
&lt;pre class="syntax-highlight"&gt;
&lt;span class="synStatement"&gt;use &lt;/span&gt;&lt;span class="synConstant"&gt;5.008001&lt;/span&gt;;
{

&lt;span class="synType"&gt;    &lt;/span&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; ClassB;&lt;/span&gt;
&lt;span class="synIdentifier"&gt;    &lt;/span&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; DESTROY &lt;/span&gt;{ }
}
{

&lt;span class="synType"&gt;    &lt;/span&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; ClassA;&lt;/span&gt;
    &lt;span class="synStatement"&gt;our&lt;/span&gt; &lt;span class="synIdentifier"&gt;@ISA&lt;/span&gt; = &lt;span class="synConstant"&gt;qw(ClassB)&lt;/span&gt;;
    *DESTROY = *ClassB::DESTROY;
    &lt;span class="synStatement"&gt;delete&lt;/span&gt; @{&lt;span class="synConstant"&gt;'ClassB::'&lt;/span&gt;}{&lt;span class="synConstant"&gt;&amp;#34;DESTROY&amp;#34;&lt;/span&gt;};

    &lt;span class="synStatement"&gt;bless&lt;/span&gt; *STDIN{IO}, &lt;span class="synConstant"&gt;&amp;#34;ClassA&amp;#34;&lt;/span&gt;;
}
&lt;/pre&gt;

			&lt;p&gt;&lt;hr&gt;&lt;/p&gt;
			&lt;p&gt;Faster.pm をいじってるときに踏んだから、なんか Faster.pm のバグだろうとおもって検討ちがいなところを調べまくって無駄に時間つかってもうた。f&lt;/p&gt;
		&lt;/div&gt;
</content>
    <category term="perl"/>
    <published>2010-02-09T00:53:39+09:00</published>
    <updated>2010-02-09T00:53:39+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100208/1265644419</id>
  </entry>
  <entry>
    <title>Building RPMs from CPAN Distributions</title>
    <link rel="alternate" href="http://perlhacks.com/2010/02/building-rpms-from-cpan-distributions.php" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"> Regular readers will know that in the past I've shown some interest in
building RPMs from CPAN distributions. It's been a while since I did much
work in this area (although I do still release the occasional module to
my RPM repository.

Over the weekend I was at FOSDEM and I attended Gabor's talk on packaging
CPAN modules for Linux distributions. This has rekindled my interest in
this area and I spent most of the train journey back from Brussels
hacking around the area.

There's one thing that has been bothering me in particular recently. The
standard RPM building mechanism (or, at least, the way it's configured in
Fedora and Centos) does something incredible brain dead when trying to
work out what other modules the current module depends on. It does it by
parsing the source code and looking for "use" statements. This means that
a module that might only be used in really obscure cases is going to be
listed as a mandatory requirement for your module.

Gabor and I actually saw an example of this over the weekend when the
Fedora packaging team raised a bug against Padre because it requires
Win32::API. Padre, of course, only uses Win32::API when being used on
Windows. And for that reason Win32::API is not listed as a dependency in
its META.yml.

And that's, of course, where the RPM builders should be going to get a
list of dependencies. META.yml contains the list of other modules that
the author wants the module to depend on. This should be seen as the
definitive list. Of course, there might be errors in that list - but that
should be addressed by raising a bug against the module.

I've poked at this problem a few times, trying to work out how the RPM
system parses the code and trying to replace that with code that looks at
META.yml instead. But the RPM system uses a baroque system of
interdependent macros and eventually they all lead to a piece of rather
clunky Perl code. So each time I've approached this problem, I've backed
off again.

The problem became more urgent when I wanted to package Plack for Fedora.
Plack supports all sorts of hosting environments and therefore includes
"use" statements loading a number of modules that most people will never
use. Fedora includes Apache2, so Apache::Request (which is for Apache1)
will never be available. It's not listed in META.YML, but it is used by
one of the modules. The RPM build system was therefore insisting that it
should be present. An impasse was reached.

Then I decided to turn the problem on its head. RPM building has two
steps. You create a spec file for the RPM and then you build the RPM
using the spec file and your original tarball. I started wondering if I
could ensure that the spec had all of the requirements (from the
META.yml). Once I'd done that I would only need to find some way to turn
off the RPM build system's default behaviour.

People packaging CPAN modules for Fedora (and Centos) use a program
called 'cpanspec' to generate spec files. I started digging into the code
there in order to find out how to insert the list of correct
dependencies.

Only to find that it has already been done. cpanspec is already doing the
right thing and generating a list of 'Requires' statements from the data
in META.yml.

Then all I needed to do was to see if I could turn off the (broken)
default RPM build behaviour which was adding spurious extra dependencies.
That proved to be easy too. It's just a case of adding %__perl_requires
%{nil} to your .rpmmacros files.

So now all of my RPMs will have only the correct dependencies listed.
This makes me very happy.

I suppose I should go back and rebuild all of the older ones too.

Oh, and because I've worked out a really easy way to generate this -
here's a spreadsheet listing which CPAN modules are available as RPMs for
Fedora. I plan to keep this list up to date (and make it much longer).
[Link now fixed]

p.s. More about my trip to FOSDEM and the Perl marketing push there over
the next couple of days.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            Regular readers will know that in the past I've shown some interest in <a href="http://www.slideshare.net/davorg/perl-in-rpmland-presentation">building RPMs from CPAN distributions</a>. It's been a while since I did much work in this area (although I do still release the occasional module to <a href="http://rpm.mag-sol.com/">my RPM repository</a>.<br/><br/>Over the weekend I was at FOSDEM and I attended Gabor's talk on <a href="http://fosdem.org/2010/schedule/events/dist_perl_cpan">packaging CPAN modules for Linux distributions</a>. This has rekindled my interest in this area and I spent most of the train journey back from Brussels hacking around the area.<br/><br/>There's one thing that has been bothering me in particular recently. The standard RPM building mechanism (or, at least, the way it's configured in Fedora and Centos) does something incredible brain dead when trying to work out what other modules the current module depends on. It does it by parsing the source code and looking for "use" statements. This means that a module that might only be used in really obscure cases is going to be listed as a mandatory requirement for your module.<br/><br/>Gabor and I actually saw an example of this over the weekend when the Fedora packaging team raised a bug against <a href="http://search.cpan.org/dist/Padre/">Padre</a> because it requires Win32::API. Padre, of course, only uses Win32::API when being used on Windows. And for that reason Win32::API is not listed as a dependency in its <a href="http://cpansearch.perl.org/src/PLAVEN/Padre-0.56/META.yml">META.yml</a>.<br/><br/>And that's, of course, where the RPM builders should be going to get a list of dependencies. META.yml contains the list of other modules that the author wants the module to depend on. This should be seen as the definitive list. Of course, there might be errors in that list - but that should be addressed by raising a bug against the module.<br/><br/>I've poked at this problem a few times, trying to work out how the RPM system parses the code and trying to replace that with code that looks at META.yml instead. But the RPM system uses a baroque system of interdependent macros and eventually they all lead to a piece of rather clunky Perl code. So each time I've approached this problem, I've backed off again.<br/><br/>The problem became more urgent when I wanted to package <a href="http://search.cpan.org/dist/Plack/">Plack</a> for Fedora. Plack supports all sorts of hosting environments and therefore includes "use" statements loading a number of modules that most people will never use. Fedora includes Apache2, so Apache::Request (which is for Apache1) will never be available. It's not listed in <a href="http://search.cpan.org/src/MIYAGAWA/Plack-0.9031/META.yml">META.YML</a>, but it is used by one of the modules. The RPM build system was therefore insisting that it should be present. An impasse was reached.<br/><br/>Then I decided to turn the problem on its head. RPM building has two steps. You create a spec file for the RPM and then you build the RPM using the spec file and your original tarball. I started wondering if I could ensure that the spec had all of the requirements (from the META.yml). Once I'd done that I would only need to find some way to turn off the RPM build system's default behaviour.<br/><br/>People packaging CPAN modules for Fedora (and Centos) use a program called 'cpanspec' to generate spec files. I started digging into the code there in order to find out how to insert the list of correct dependencies.<br/><br/>Only to find that it has already been done. cpanspec is already doing the right thing and generating a list of 'Requires' statements from the data in META.yml.<br/><br/>Then all I needed to do was to see if I could turn off the (broken) default RPM build behaviour which was adding spurious extra dependencies. That proved to be easy too. It's just a case of adding <tt>%__perl_requires %{nil}</tt> to your .rpmmacros files.<br/><br/>So now all of my RPMs will have only the correct dependencies listed. This makes me very happy.<br/><br/>I suppose I should go back and rebuild all of the older ones too.<br/><br/>Oh, and because I've worked out a really easy way to generate this - here's <a href="http://spreadsheets.google.com/pub?key=tVoSlaYU1SGovwwjV0fqt9Q&amp;output=html">a spreadsheet listing which CPAN modules are available as RPMs for Fedora</a>. I plan to keep this list up to date (and make it much longer). [Link now fixed]<br/><br/>p.s. More about my trip to FOSDEM and the Perl marketing push there over the next couple of days.<br/>
            
        </div>
    </content>
    <category term="CPAN cpan fedora linux rpm"/>
    <published>2010-02-08T14:01:02+01:00</published>
    <updated>2010-02-08T14:01:02+01:00</updated>
    <author>
      <name>Dave Cross</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:perlhacks.com,2010://1.47</id>
  </entry>
  <entry>
    <title>The typo trap: a farcical FAQ</title>
    <link rel="alternate" href="http://use.perl.org/~masak/journal/40167?from=rss" type="text/html"/>
    <summary type="text">Help! I'm getting the error "invoke() not implemented in class 'Undef'"
in my large application. What did I do wrong?

You've mistyped a class name which sits inside a namespace.

How am I supposed to figure that out?

I didn't say it was a particularly good error message.

It's like this: if you mistype a class name which is not in a namespace,
you'll get an informative error message:

$ perl6 -e 'A.foo'
Could not find non-existent sub A
in Main (file src/gen_setting.pm, line 324)

However, if you mistype a class name which is in a namespace, you will
get an uninformative error message:

$ perl6 -e 'A::B.foo'
invoke() not implemented in class 'Undef'
in Main (file &lt;unknown&gt;, line &lt;unknown&gt;)

So there's your error message. Linking it to the actual cause is
something which you'll learn by experience.

So in that case, I don't get the name of the class which was mistyped in
my program?

Correct.

And I don't get the line number of my typo?

Indeed not.

Or the file?

Right. You'll get no information about the location of the typo.

Is that intentional?

Well, no. As you see from the error message above, the information is
meant to be printed, but it comes out as (file &lt;unknown&gt;, line &lt;unknown&gt;)
instead.

Why?

Rakudo is built on top of Parrot. Usually, Rakudo generates its own error
messages, but in some cases, Parrot will also generate an error. The
error invoke() not implemented in class 'Undef' is such a case. When a
Parrot-internal error like this one occurs, Rakudo will not be able to
extract the annotation information required to provide a sensible line
number and file.

I... I see.

Yeah. Sorry about that.

Are you able to pick up the irony in the fact that when I use namespaces
to help mitigate the complexity of my project, I end up with an error
message that in fact makes it harder for me to manage the complexity of
my project?

Hold on.

Yes. We are able to pick up the irony in that. Quite easily, in fact.

Consider not using namespaces at the present juncture. They are very
useful, but they are also known as a frequent source of annoyances like
this.

By the way, I couldn't help but note that the line number and file
information in your first example doesn't make any sense either. What the
heck is src/gen_setting.pm and line 324?

Well, uh, that's the last line of internal Rakudo code that actually has
a working line-and-file annotation. It's nothing that should reach the
user, really.

So that's kinda broken, too?

Annotations are currently broken, yes. Apologies.

Back to my mistyped type name. My program is distributed over fifteen
modules and ten thousand lines of code. How do you propose I find my
typo?

First off, we recommend that you compile often. That way, the diff from
the last working code will not be too large, and you will not have to
visually scan so much text hunting for your typo.

Secondly, it's often useful to have your project in a version tracker
such as Git, so that you can do git diff to see the changes against the
index, or against the latest commit.

Thirdly, when all else fails, you can always insert print statements into
your code, to try to bisect the origin of the error.

So in other words, Rakudo is no help whatsoever when this occurs?

Now, that's not quite fair. Rakudo tells you that the error occurs.
That's actually useful information.

And you consider that adequate?

No, I didn't say that! No-one is happy about this situation. It's just
the way things are.

So it can't be fixed?

Theoretically, yes. But not easily. Remember that the error occurs in
Parrot.

Don't Rakudo and Parrot developers confer with each other?

Oh, sure we do. Do not assume that we're deliberately causing this
situation. It's just that the current way Rakudo and Parrot are welded
together makes the situation non-trivial to rectify.

So this problem is going to go away with the advent of the new ng branch?

There's nothing to indicate that this would be the case. In ng, you
currently get a Null PMC access:

$ ./perl6 -e 'A::B.foo' # ng branch
Null PMC access in invoke()
current instr.: '_block14' pc 29 (EVAL_1:0)
called from Sub '!UNIT_START' pc 984 (src/glue/run.pir:17)
called from Sub 'perl6;PCT;HLLCompiler;eval' pc -1 ((unknown file):-1)
called from Sub 'perl6;PCT;HLLCompiler;command_line' pc 1489
(src/PCT/HLLCompiler.pir:794)
called from Sub 'perl6;Perl6;Compiler;main' pc -1 ((unknown file):-1)

To its credit, Rakudo ng does provide more information in this case, but
unfortunately the information is of a kind which was concealed from the
user in Rakudo master about a year ago (because it tended to be very
uninformative).

Just to summarize: this all sucks, right?

That would be a succinct description of the state of this particular
error message, yes.

I heard that the Perl 6 community has adopted very high standards with
respect to error messages. There's talk about "awesome error messages",
and last summer I was in the audience when Larry Wall demonstrated how
good Perl 6 was at reporting error messages to the user. How does this
error message square with all of that?

The awesome error messages are like a platonic ideal towards which all
implementations aspire. Rakudo, being rooted in our imperfect physical
world, doesn't always get all the way. Yet.

I'm about to go visually scan ten thousand lines of code, looking for
where my error message might have originated. Any last words?

We value your efforts as an early adopter of Rakudo. Your feedback is
important to us. Have a nice day.</summary>
    <content type="html">&lt;p&gt; &lt;b&gt;Help! I'm getting the error "invoke() not implemented in class 'Undef'" in my large application. What did I do wrong?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;You've mistyped a class name which sits inside a namespace.&lt;/p&gt;&lt;p&gt; &lt;b&gt;How am I supposed to figure that out?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;I didn't say it was a particularly good error message.&lt;/p&gt;&lt;p&gt;It's like this: if you mistype a class name which is not in a namespace, you'll get an informative error message:&lt;/p&gt;&lt;p&gt; &lt;code&gt;$ perl6 -e 'A.foo'&lt;br&gt;
Could not find non-existent sub A&lt;br&gt;
in Main (file src/gen_setting.pm, line 324)&lt;/code&gt; &lt;/p&gt;&lt;p&gt;However, if you mistype a class name which &lt;em&gt;is&lt;/em&gt; in a namespace, you will get an &lt;em&gt;un&lt;/em&gt;informative error message:&lt;/p&gt;&lt;p&gt; &lt;code&gt;$ perl6 -e 'A::B.foo'&lt;br&gt;
invoke() not implemented in class 'Undef'&lt;br&gt;
in Main (file &amp;lt;unknown&amp;gt;, line &amp;lt;unknown&amp;gt;)&lt;/code&gt; &lt;/p&gt;&lt;p&gt;So there's your error message. Linking it to the actual cause is something which you'll learn by experience.&lt;/p&gt;&lt;p&gt; &lt;b&gt;So in that case, I don't get the name of the class which was mistyped in my program?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Correct.&lt;/p&gt;&lt;p&gt; &lt;b&gt;And I don't get the line number of my typo?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Indeed not.&lt;/p&gt;&lt;p&gt; &lt;b&gt;Or the file?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Right. You'll get no information about the location of the typo.&lt;/p&gt;&lt;p&gt; &lt;b&gt;Is that intentional?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Well, no. As you see from the error message above, the information is meant to be printed, but it comes out as &lt;code&gt;(file &amp;lt;unknown&amp;gt;, line &amp;lt;unknown&amp;gt;)&lt;/code&gt; instead.&lt;/p&gt;&lt;p&gt; &lt;b&gt;Why?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Rakudo is built on top of Parrot. Usually, Rakudo generates its own error messages, but in some cases, Parrot will also generate an error. The error &lt;code&gt;invoke() not implemented in class 'Undef'&lt;/code&gt; is such a case. When a Parrot-internal error like this one occurs, Rakudo will not be able to extract the annotation information required to provide a sensible line number and file.&lt;/p&gt;&lt;p&gt; &lt;b&gt;I... I see.&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Yeah. Sorry about that.&lt;/p&gt;&lt;p&gt; &lt;b&gt;Are you able to pick up the irony in the fact that when I use namespaces to help mitigate the complexity of my project, I end up with an error message that in fact makes it harder for me to manage the complexity of my project?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Hold on.&lt;/p&gt;&lt;p&gt;Yes. We are able to pick up the irony in that. Quite easily, in fact.&lt;/p&gt;&lt;p&gt;Consider not using namespaces at the present juncture. They are very useful, but they are also known as a frequent source of annoyances like this.&lt;/p&gt;&lt;p&gt; &lt;b&gt;By the way, I couldn't help but note that the line number and file information in your first example doesn't make any sense either. What the heck is &lt;code&gt;src/gen_setting.pm&lt;/code&gt; and &lt;code&gt;line 324&lt;/code&gt;?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Well, uh, that's the last line of internal Rakudo code that actually has a working line-and-file annotation. It's nothing that should reach the user, really.&lt;/p&gt;&lt;p&gt; &lt;b&gt;So that's kinda broken, too?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Annotations are currently broken, yes. Apologies.&lt;/p&gt;&lt;p&gt; &lt;b&gt;Back to my mistyped type name. My program is distributed over fifteen modules and ten thousand lines of code. How do you propose I find my typo?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;First off, we recommend that you compile often. That way, the diff from the last working code will not be too large, and you will not have to visually scan so much text hunting for your typo.&lt;/p&gt;&lt;p&gt;Secondly, it's often useful to have your project in a version tracker such as Git, so that you can do &lt;code&gt;git diff&lt;/code&gt; to see the changes against the index, or against the latest commit.&lt;/p&gt;&lt;p&gt;Thirdly, when all else fails, you can always insert print statements into your code, to try to bisect the origin of the error.&lt;/p&gt;&lt;p&gt; &lt;b&gt;So in other words, Rakudo is no help whatsoever when this occurs?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Now, that's not quite fair. Rakudo tells you &lt;em&gt;that&lt;/em&gt; the error occurs. That's actually useful information.&lt;/p&gt;&lt;p&gt; &lt;b&gt;And you consider that adequate?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;No, I didn't say that! No-one is happy about this situation. It's just the way things are.&lt;/p&gt;&lt;p&gt; &lt;b&gt;So it can't be fixed?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Theoretically, yes. But not easily. Remember that the error occurs in Parrot.&lt;/p&gt;&lt;p&gt; &lt;b&gt;Don't Rakudo and Parrot developers confer with each other?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;Oh, sure we do. Do not assume that we're deliberately causing this situation. It's just that the current way Rakudo and Parrot are welded together makes the situation non-trivial to rectify.&lt;/p&gt;&lt;p&gt; &lt;b&gt;So this problem is going to go away with the advent of the new &lt;code&gt;ng&lt;/code&gt; branch?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;There's nothing to indicate that this would be the case. In &lt;code&gt;ng&lt;/code&gt;, you currently get a Null PMC access:&lt;/p&gt;&lt;p&gt; &lt;code&gt;$&lt;nobr&gt; &lt;wbr&gt;&lt;/nobr&gt;./perl6 -e 'A::B.foo' # ng branch&lt;br&gt;
Null PMC access in invoke()&lt;br&gt;
current instr.: '_block14' pc 29 (EVAL_1:0)&lt;br&gt;
called from Sub '!UNIT_START' pc 984 (src/glue/run.pir:17)&lt;br&gt;
called from Sub 'perl6;PCT;HLLCompiler;eval' pc -1 ((unknown file):-1)&lt;br&gt;
called from Sub 'perl6;PCT;HLLCompiler;command_line' pc 1489 (src/PCT/HLLCompiler.pir:794)&lt;br&gt;
called from Sub 'perl6;Perl6;Compiler;main' pc -1 ((unknown file):-1)&lt;/code&gt; &lt;/p&gt;&lt;p&gt;To its credit, Rakudo &lt;code&gt;ng&lt;/code&gt; does provide more information in this case, but unfortunately the information is of a kind which was concealed from the user in Rakudo &lt;code&gt;master&lt;/code&gt; about a year ago (because it tended to be very uninformative).&lt;/p&gt;&lt;p&gt; &lt;b&gt;Just to summarize: this all sucks, right?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;That would be a succinct description of the state of this particular error message, yes.&lt;/p&gt;&lt;p&gt; &lt;b&gt;I heard that the Perl 6 community has adopted very high standards with respect to error messages. There's talk about "awesome error messages", and last summer I was in the audience when Larry Wall demonstrated how good Perl 6 was at reporting error messages to the user. How does this error message square with all of that?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;The awesome error messages are like a platonic ideal towards which all implementations aspire. Rakudo, being rooted in our imperfect physical world, doesn't always get all the way. Yet.&lt;/p&gt;&lt;p&gt; &lt;b&gt;I'm about to go visually scan ten thousand lines of code, looking for where my error message might have originated. Any last words?&lt;/b&gt; &lt;/p&gt;&lt;p&gt;We value your efforts as an early adopter of Rakudo. Your feedback is important to us. Have a nice day.&lt;/p&gt;</content>
    <category term="perl6"/>
    <published>2010-02-08T12:54:56Z</published>
    <updated>2010-02-08T12:54:56Z</updated>
    <author>
      <name>masak</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://use.perl.org/~masak/journal/40167?from=rss</id>
  </entry>
  <entry>
    <title>Rebuilding my development area</title>
    <link rel="alternate" href="http://vampiresoftware.blogspot.com/2010/02/rebuilding-my-development-area.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I thought it was about time to get around to rebuilding my development
area, for a few reasons:

1) Housekeeping - My dev area was getting a lot of junk floating around,
and rather than just go through and delete, I thought it better to
restart

2) About time I upgraded to perl-5.10.1

3) I need to start up a VM soon, and thought it a good opportunity to set
make notes about what was needed

4) cpan/cpanplus wasn't working for me

5) I've never had GD working properly, and I could be about to lose my
desktop at work

So plenty of reasons. I also wanted to try to structure how I setup
various apps, so that it should (in theory) be easier to upgrade an of
them. Getting further on, I think this might not be so worthwhile, but at
least it's a try.

Here is 'What I Have Done' so far

INITIAL SETUP:

In $HOME

mkdir dev
cd dev

This gives me a base dev directory to use

PERL:

mkdir perl

Download the version of perl you want to install

mkdir perl/ (i.e. mkdir perl/5.10.1)

Unarchive the download and go into the directory for created from
unarchiving and do the following

./Configure -des -Dprefix=$HOME/dev/perl/
make
make test (go away and make a cup of tea)
make install

This will now give you in $HOME/dev/perl/ the bin/, lib/ and man/
directories

Once you have done this, symlink this version to $HOME/dev/perl/current,
and add $HOME/dev/perl/current/bin to $PATH

This should make your default perl $HOME/dev/perl/current/bin/perl

Since you have done this, if you now want to download and try another
perl, then you can do the same, and just switch the current softlink


LIBGD:

You need to download
freetype-2.3.11.tar.gz
jpegsrc.v8.tar.gz
libpng-1.2.23.tar.gz
zlib-1.2.3.tar.gz
gd-2.0.35.tar.gz

unpack and install

freetype

cd freetype-2.3.11
./configure --prefix=$HOME/dev
make install
cd ..

jpeg-8
(need to look at)
cd jpeg-8
./configure --prefix=$HOME/dev --enable-shared --enable-static
make
make install
cd ..

zlib-1.2.3

cd zlib-1.2.3
./configure --prefix=$HOME/dev
make
make install
cd ..

[edit] libpng-1.2.x

cd libpng-1.2.x
CFLAGS="-I$HOME/dev/include" LDFLAGS="-L$HOME/dev/lib" ./configure
--prefix=$HOME/dev
make
make install
cd ..

[edit] gd-2.0.35

cd gd-2.0.35
CFLAGS="-I$HOME/dev/include" LDFLAGS="-L$HOME/dev/lib" ./configure
--prefix=$HOME/dev --with-png=$HOME/dev --with-freetype=$HOME/dev
--with-jpeg=$HOME/dev
make INCLUDEDIRS="-I. -I$HOME/dev" LIBDIRS="-L$HOME/dev" LIBS="-lgd -lpng
-lz -lm" CFLAGS="-O -DHAVE_LIBPNG"
make install
cd..

For these, I chose not to create individual versions of them. You will
also note that libpng is 1.2 and jpeg is V8 but says need to look at,
since this doesn't seem to work with this version of gd. However, since I
mostly create png images, I'm not too concerned at this time. Must sort
it though eventually.

Graphviz:

This is needed for installation of some CPAN modules
http://www.graphviz.org

Follow instructions on how to install, using $HOME/dev as the prefix

Again, no version specific route taken

SLEEPYCAT libdb-4:

Download from Oracle

unarchive latest version and install

cd build_unix/
../dist/configure --prefix=$HOME/dev
make
make install

Again, no version specific route, and needed for some CPAN modules

CPAN modules:

cpanp is the recommended method to download and install modules from cpan

type

cpanp

and the interactive shell will be launched

If this is the first time, then enter the following

s conf prereqs 1; s save

This will save some of the hassle of needing to confirm installation of
required modules

These are chosen because I need to set up a webserver, I work in a Bio
place, and some are personal choice. Obviously, if you need others, or
not some of these, then pick and choose. They are also loaded in this
order for convenience and dependencies.

To install a cpan module, just type

i

i Bundle::LWP
i LWP::Parallel::UserAgent
i YAML::Tiny
i Module::Build
i Module::PortablePath
i Task::Moose (select all the optional loads)
i IO::Stringy
i Calendar::Simple
i List::MoreUtils (This had a checksum error, so manually downloaded)
i DateTime
i DateTime::Format::ICal
i iCal::Parser
i Digest::SHA1
i Class::Std
i Crypt::CBC
i Crypt::Blowfish
i MIME::Lite
i DBI
i DBD::mysql # force install if you've no test database available, also
requires the mysql client development headers - mysql_config needs to be
in your $PATH (probably ~/dev/bin).
i DBD::SQLite
i Tie::IxHash
i XML::XPathEngine
i XML::Parser (again, I got a dodgy md5)
i XML::XPath
i HTML::TreeBuilder
i XML::SAX
i XML::Simple
i XML::Handler::YAWriter
i XML::Filter::BufferText
i MLDBM
i Jcode
i Spreadsheet::WriteExcel
i Unicode::Map
i Apache::DBI
i Readonly (another dodgy md5)
i XML::FeedLite (causes lots of prereqs to be installed - would suggest a
cup of tea if you have selected auto download of prereqs)
i Chart::OFC
i YAML
i Digest::SHA
i Ace # force install if fails to make as it may have problems connecting
to Ace database during tests
i Bio::ASN1::EntrezGene # force install if fails as it looks as though
for tests it needs a non-existent CPAN module
i Bundle::BioPerl
i GD (Why has this failed tests?)
i B/BI/BIRNEY/bioperl-1.4.tar.gz # Requires sleepycat libdb-4 to pass
tests
i Bio::Das
i Bio::Das::Lite
i App::Ack

manually download and install DB_File - as you need to Change config.in
to point at dev/lib and dev/include
manually download and install BerkeleyDB - as you need to Change
config.in as above.

APACHE and MOD-PERL:

Apache = httpd-2.2.14;

http://httpd.apache.org/download.cgi

in dev, mkdir -p apache/2.2.14
cd apache
ln -s 2.2.14/ current

This gives space to install this version of apache into, and a softlink
to the version we want to use (similar to perl above)

export LD_LIBRARY_PATH=$HOME/dev/lib
./configure --prefix=$HOME/dev/apache/2.2.14 LDFLAGS="-L/$HOME/dev/lib"

add $HOME/dev/apache/current/bin to $PATH

mod_perl 2.0:

http://perl.apache.org/download/index.html

Get latest version of 2.0
$HOME/dev/bin/perl Makefile.PL
# follow instructions, e.g. apxs is at $HOME/dev/apache/current/bin/apxs

make
make install

Change/create the $HOME/dev/apache/current/conf/httpd.conf and
$HOME/dev/apache/current/conf/perlconfig.ini as you need to.

Catalyst:

Now the biggie. Catalyst has lots of dependencies. It will take some
time, plus it is interactive.
Just install everything - except the extra DBD supports.
You can do them in your own time, but they may make the Install fall over
now, which you don't want.

cpanp
i Task::Catalyst

If you have got through this, then congrats.

I have also downloaded into my dev area subversion and git, and have
tried to do ImageMagick (although this is erroring that my C compiler
won't compile executables, even though it has done svn and git).

subversion:

Retrieve the latest version and dependency from
http://subversion.apache.org/source-code.html
unpack both, the dependency folder should end up in the same directory,
and will then be installed with svn

mkdir -p $HOME/dev/subversion/
cd $HOME/dev/subversion
ln -s current

cd into unpacked folder

./configure --prefix=$HOME/dev/subversion/
--eprefix=$HOME/dev/subversion/
make
make install

add $HOME/dev/subversion/current/bin to your $PATH

This will enable you to have/try multiple versions of svn in the same way
as Perl and Apache above

git:

Retrieve the latest version from http://git-scm.com/
unpack

mkdir -p $HOME/dev/git/
cd $HOME/dev/git
ln -s current

make configure
./configure --prefix=$HOME/dev/git/
make
make install (had to do as root)

ImageMagick:

problem with my gcc version at this time

mkdir -p $HOME/dev/imageMagick/
cd $HOME/dev/imageMagick
ln -s current

./configure PREFIX=/Users/ajb/dev/imageMagick/6.5.9
EXEC-PREFIX=/Users/ajb/dev/imageMagick/6.5.9 LIBS=-l/Users/ajb/dev/lib
--enable-shared --disable-static

After this, you should have a nice fairly 'clean' version of a dev area.
If you want ot install other stuff, then I would recommend the method
suggested for versioning the download you have. (I can also recommend the
MOCA installation idea for mysql, although I choose to not have that in
my dev area).

Once inside this, I then create folders for my projects, using svn or git
to version control within those folders, just adding the directories to
my path as I need to.

Note: I am using MAC OSX Leopard. At times for the make install, I have
needed to sudo make install. I accept no liability for anything that
happens should you follow these instructions on any system, but hope that
they might be useful for anyone who would like to set up a dev/test area,
but are not sure how to go about it.

Cheers</div>
    </summary>
    <content type="text">I thought it was about time to get around to rebuilding my development area, for a few reasons:&lt;br /&gt;&lt;br /&gt;1) Housekeeping - My dev area was getting a lot of junk floating around, and rather than just go through and delete, I thought it better to restart&lt;br /&gt;&lt;br /&gt;2) About time I upgraded to perl-5.10.1&lt;br /&gt;&lt;br /&gt;3) I need to start up a VM soon, and thought it a good opportunity to set make notes about what was needed&lt;br /&gt;&lt;br /&gt;4) cpan/cpanplus wasn't working for me&lt;br /&gt;&lt;br /&gt;5) I've never had GD working properly, and I could be about to lose my desktop at work&lt;br /&gt;&lt;br /&gt;So plenty of reasons. I also wanted to try to structure how I setup various apps, so that it should (in theory) be easier to upgrade an of them. Getting further on, I think this might not be so worthwhile, but at least it's a try.&lt;br /&gt;&lt;br /&gt;Here is 'What I Have Done' so far&lt;br /&gt;&lt;br /&gt;INITIAL SETUP:&lt;br /&gt;&lt;br /&gt;In $HOME&lt;br /&gt;&lt;br /&gt;mkdir dev&lt;br /&gt;cd dev&lt;br /&gt;&lt;br /&gt;This gives me a base dev directory to use&lt;br /&gt;&lt;br /&gt;PERL:&lt;br /&gt;&lt;br /&gt;mkdir perl&lt;br /&gt;&lt;br /&gt;Download the version of perl you want to install&lt;br /&gt;&lt;br /&gt;mkdir perl/&lt;perl_version_no&gt; (i.e. mkdir perl/5.10.1)&lt;br /&gt;&lt;br /&gt;Unarchive the download and go into the directory for created from unarchiving and do the following&lt;br /&gt;&lt;br /&gt;./Configure -des -Dprefix=$HOME/dev/perl/&lt;perl_version_no&gt;&lt;br /&gt;make&lt;br /&gt;make test (go away and make a cup of tea)&lt;br /&gt;make install&lt;br /&gt;&lt;br /&gt;This will now give you in $HOME/dev/perl/&lt;perl_version_no&gt; the bin/, lib/ and man/ directories&lt;br /&gt;&lt;br /&gt;Once you have done this, symlink this version to $HOME/dev/perl/current, and add $HOME/dev/perl/current/bin to $PATH&lt;br /&gt;&lt;br /&gt;This should make your default perl $HOME/dev/perl/current/bin/perl&lt;br /&gt;&lt;br /&gt;Since you have done this, if you now want to download and try another perl, then you can do the same, and just switch the current softlink&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;LIBGD:&lt;br /&gt;&lt;br /&gt;You need to download&lt;br /&gt;freetype-2.3.11.tar.gz&lt;br /&gt;jpegsrc.v8.tar.gz&lt;br /&gt;libpng-1.2.23.tar.gz&lt;br /&gt;zlib-1.2.3.tar.gz&lt;br /&gt;gd-2.0.35.tar.gz&lt;br /&gt;&lt;br /&gt;unpack and install&lt;br /&gt;&lt;br /&gt;freetype&lt;br /&gt;&lt;br /&gt;cd freetype-2.3.11&lt;br /&gt;./configure --prefix=$HOME/dev&lt;br /&gt;make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;jpeg-8&lt;br /&gt;(need to look at)&lt;br /&gt;cd jpeg-8&lt;br /&gt;./configure --prefix=$HOME/dev --enable-shared --enable-static&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;zlib-1.2.3&lt;br /&gt;&lt;br /&gt;cd zlib-1.2.3&lt;br /&gt;./configure --prefix=$HOME/dev&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;[edit] libpng-1.2.x&lt;br /&gt;&lt;br /&gt;cd libpng-1.2.x&lt;br /&gt;CFLAGS="-I$HOME/dev/include" LDFLAGS="-L$HOME/dev/lib" ./configure --prefix=$HOME/dev&lt;br /&gt;make&lt;br /&gt;make install &lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;[edit] gd-2.0.35&lt;br /&gt;&lt;br /&gt;cd gd-2.0.35&lt;br /&gt;CFLAGS="-I$HOME/dev/include" LDFLAGS="-L$HOME/dev/lib" ./configure --prefix=$HOME/dev --with-png=$HOME/dev --with-freetype=$HOME/dev --with-jpeg=$HOME/dev&lt;br /&gt;make INCLUDEDIRS="-I. -I$HOME/dev" LIBDIRS="-L$HOME/dev" LIBS="-lgd -lpng -lz -lm" CFLAGS="-O -DHAVE_LIBPNG"&lt;br /&gt;make install&lt;br /&gt;cd..&lt;br /&gt;&lt;br /&gt;For these, I chose not to create individual versions of them. You will also note that libpng is 1.2 and jpeg is V8 but says need to look at, since this doesn't seem to work with this version of gd. However, since I mostly create png images, I'm not too concerned at this time. Must sort it though eventually.&lt;br /&gt;&lt;br /&gt;Graphviz:&lt;br /&gt;&lt;br /&gt;This is needed for installation of some CPAN modules&lt;br /&gt;http://www.graphviz.org&lt;br /&gt;&lt;br /&gt;Follow instructions on how to install, using $HOME/dev as the prefix&lt;br /&gt;&lt;br /&gt;Again, no version specific route taken&lt;br /&gt;&lt;br /&gt;SLEEPYCAT libdb-4:&lt;br /&gt;&lt;br /&gt;Download from Oracle&lt;br /&gt;&lt;br /&gt;unarchive latest version and install&lt;br /&gt;&lt;br /&gt;cd build_unix/&lt;br /&gt;../dist/configure --prefix=$HOME/dev&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;br /&gt;Again, no version specific route, and needed for some CPAN modules&lt;br /&gt;&lt;br /&gt;CPAN modules:&lt;br /&gt;&lt;br /&gt;cpanp is the recommended method to download and install modules from cpan&lt;br /&gt;&lt;br /&gt;type &lt;br /&gt;&lt;br /&gt;cpanp&lt;br /&gt;&lt;br /&gt;and the interactive shell will be launched&lt;br /&gt;&lt;br /&gt;If this is the first time, then enter the following&lt;br /&gt;&lt;br /&gt;s conf prereqs 1; s save&lt;br /&gt;&lt;br /&gt;This will save some of the hassle of needing to confirm installation of required modules&lt;br /&gt;&lt;br /&gt;These are chosen because I need to set up a webserver, I work in a Bio place, and some are personal choice. Obviously, if you need others, or not some of these, then pick and choose. They are also loaded in this order for convenience and dependencies.&lt;br /&gt;&lt;br /&gt;To install a cpan module, just type &lt;br /&gt;&lt;br /&gt;i &lt;module&gt;&lt;br /&gt;&lt;br /&gt;i Bundle::LWP&lt;br /&gt;i LWP::Parallel::UserAgent&lt;br /&gt;i YAML::Tiny&lt;br /&gt;i Module::Build&lt;br /&gt;i Module::PortablePath&lt;br /&gt;i Task::Moose (select all the optional loads)&lt;br /&gt;i IO::Stringy&lt;br /&gt;i Calendar::Simple&lt;br /&gt;i List::MoreUtils (This had a checksum error, so manually downloaded)&lt;br /&gt;i DateTime&lt;br /&gt;i DateTime::Format::ICal&lt;br /&gt;i iCal::Parser&lt;br /&gt;i Digest::SHA1&lt;br /&gt;i Class::Std&lt;br /&gt;i Crypt::CBC&lt;br /&gt;i Crypt::Blowfish&lt;br /&gt;i MIME::Lite&lt;br /&gt;i DBI&lt;br /&gt;i DBD::mysql  # force install if you've no test database available, also requires the mysql client development headers - mysql_config needs to be in your $PATH (probably ~/dev/bin).&lt;br /&gt;i DBD::SQLite&lt;br /&gt;i Tie::IxHash&lt;br /&gt;i XML::XPathEngine&lt;br /&gt;i XML::Parser (again, I got a dodgy md5)&lt;br /&gt;i XML::XPath&lt;br /&gt;i HTML::TreeBuilder&lt;br /&gt;i XML::SAX&lt;br /&gt;i XML::Simple&lt;br /&gt;i XML::Handler::YAWriter&lt;br /&gt;i XML::Filter::BufferText&lt;br /&gt;i MLDBM&lt;br /&gt;i Jcode&lt;br /&gt;i Spreadsheet::WriteExcel&lt;br /&gt;i Unicode::Map&lt;br /&gt;i Apache::DBI&lt;br /&gt;i Readonly (another dodgy md5)&lt;br /&gt;i XML::FeedLite (causes lots of prereqs to be installed - would suggest a cup of tea if you have selected auto download of prereqs)&lt;br /&gt;i Chart::OFC&lt;br /&gt;i YAML&lt;br /&gt;i Digest::SHA&lt;br /&gt;i Ace  # force install if fails to make as it may have problems connecting to Ace database during tests&lt;br /&gt;i Bio::ASN1::EntrezGene  # force install if fails as it looks as though for tests it needs a non-existent CPAN module&lt;br /&gt;i Bundle::BioPerl&lt;br /&gt;i GD (Why has this failed tests?)&lt;br /&gt;i B/BI/BIRNEY/bioperl-1.4.tar.gz   # Requires sleepycat libdb-4 to pass tests&lt;br /&gt;i Bio::Das&lt;br /&gt;i Bio::Das::Lite&lt;br /&gt;i App::Ack&lt;br /&gt;&lt;br /&gt;manually download and install DB_File - as you need to Change config.in to point at dev/lib and dev/include&lt;br /&gt;manually download and install BerkeleyDB - as you need to Change config.in as above.&lt;br /&gt;&lt;br /&gt;APACHE and MOD-PERL:&lt;br /&gt;&lt;br /&gt;Apache = httpd-2.2.14;&lt;br /&gt;&lt;br /&gt;http://httpd.apache.org/download.cgi&lt;br /&gt;&lt;br /&gt;in dev, mkdir -p apache/2.2.14&lt;br /&gt;cd apache&lt;br /&gt;ln -s 2.2.14/ current&lt;br /&gt;&lt;br /&gt;This gives space to install this version of apache into, and a softlink to the version we want to use (similar to perl above)&lt;br /&gt;&lt;br /&gt;export LD_LIBRARY_PATH=$HOME/dev/lib&lt;br /&gt;./configure --prefix=$HOME/dev/apache/2.2.14 LDFLAGS="-L/$HOME/dev/lib"&lt;br /&gt;&lt;br /&gt;add $HOME/dev/apache/current/bin to $PATH&lt;br /&gt;&lt;br /&gt;mod_perl 2.0:&lt;br /&gt;&lt;br /&gt;http://perl.apache.org/download/index.html&lt;br /&gt;&lt;br /&gt;Get latest version of 2.0&lt;br /&gt;$HOME/dev/bin/perl Makefile.PL&lt;br /&gt;# follow instructions, e.g. apxs is at $HOME/dev/apache/current/bin/apxs &lt;br /&gt;&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;br /&gt;Change/create the $HOME/dev/apache/current/conf/httpd.conf and $HOME/dev/apache/current/conf/perlconfig.ini as you need to.&lt;br /&gt;&lt;br /&gt;Catalyst:&lt;br /&gt;&lt;br /&gt;Now the biggie. Catalyst has lots of dependencies. It will take some time, plus it is interactive.&lt;br /&gt;Just install everything - except the extra DBD supports.&lt;br /&gt;You can do them in your own time, but they may make the Install fall over now, which you don't want.&lt;br /&gt;&lt;br /&gt;cpanp&lt;br /&gt;i Task::Catalyst&lt;br /&gt;&lt;br /&gt;If you have got through this, then congrats. &lt;br /&gt;&lt;br /&gt;I have also downloaded into my dev area subversion and git, and have tried to do ImageMagick (although this is erroring that my C compiler won't compile executables, even though it has done svn and git).&lt;br /&gt;&lt;br /&gt;subversion:&lt;br /&gt;&lt;br /&gt;Retrieve the latest version and dependency from http://subversion.apache.org/source-code.html&lt;br /&gt;unpack both, the dependency folder should end up in the same directory, and will then be installed with svn&lt;br /&gt;&lt;br /&gt;mkdir -p $HOME/dev/subversion/&lt;version_number&gt;&lt;br /&gt;cd $HOME/dev/subversion&lt;br /&gt;ln -s &lt;version_number&gt; current&lt;br /&gt;&lt;br /&gt;cd into unpacked folder&lt;br /&gt;&lt;br /&gt;./configure --prefix=$HOME/dev/subversion/&lt;version_number&gt; --eprefix=$HOME/dev/subversion/&lt;version_number&gt;&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;br /&gt;add $HOME/dev/subversion/current/bin to your $PATH&lt;br /&gt;&lt;br /&gt;This will enable you to have/try multiple versions of svn in the same way as Perl and Apache above&lt;br /&gt;&lt;br /&gt;git:&lt;br /&gt;&lt;br /&gt;Retrieve the latest version from http://git-scm.com/&lt;br /&gt;unpack&lt;br /&gt;&lt;br /&gt;mkdir -p $HOME/dev/git/&lt;version_number&gt;&lt;br /&gt;cd $HOME/dev/git&lt;br /&gt;ln -s &lt;version_number&gt; current&lt;br /&gt;&lt;br /&gt;make configure&lt;br /&gt;./configure --prefix=$HOME/dev/git/&lt;version_number&gt;&lt;br /&gt;make&lt;br /&gt;make install (had to do as root)&lt;br /&gt;&lt;br /&gt;ImageMagick:&lt;br /&gt;&lt;br /&gt;problem with my gcc version at this time&lt;br /&gt;&lt;br /&gt;mkdir -p $HOME/dev/imageMagick/&lt;version_number&gt;&lt;br /&gt;cd $HOME/dev/imageMagick&lt;br /&gt;ln -s &lt;version_number&gt; current&lt;br /&gt;&lt;br /&gt;./configure PREFIX=/Users/ajb/dev/imageMagick/6.5.9 EXEC-PREFIX=/Users/ajb/dev/imageMagick/6.5.9 LIBS=-l/Users/ajb/dev/lib --enable-shared --disable-static&lt;br /&gt;&lt;br /&gt;After this, you should have a nice fairly 'clean' version of a dev area. If you want ot install other stuff, then I would recommend the method suggested for versioning the download you have. (I can also recommend the MOCA installation idea for mysql, although I choose to not have that in my dev area).&lt;br /&gt;&lt;br /&gt;Once inside this, I then create folders for my projects, using svn or git to version control within those folders, just adding the directories to my path as I need to.&lt;br /&gt;&lt;br /&gt;Note: I am using MAC OSX Leopard. At times for the make install, I have needed to sudo make install. I accept no liability for anything that happens should you follow these instructions on any system, but hope that they might be useful for anyone who would like to set up a dev/test area, but are not sure how to go about it.&lt;br /&gt;&lt;br /&gt;Cheers&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <published>2010-02-08T08:51:00Z</published>
    <updated>2010-02-08T08:51:00Z</updated>
    <author>
      <name>Andy Brown - SetitesUK</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-1158653486009791669.post-7571128117128325026</id>
  </entry>
  <entry>
    <title>Ataque de denegación de servicio dedicado a Perl</title>
    <link rel="alternate" href="http://www.perlhispano.com/cgi-bin/index.cgi?action=viewnews&amp;id=35" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Ataque de denegación de servicio dedicado a Perl CPAN se origina desde
redes de Microsoft.

En recientes días, los usuarios de CPAN de Perl han estado experimentando
problemas para acceder hacia sus sitios, bases de datos ...</div>
    </summary>
    <content type="html">
      &lt;font color="Red"&gt;&lt;b&gt;Ataque de denegación de servicio dedicado a Perl CPAN se origina desde redes de Microsoft.&lt;/b&gt;&lt;/font&gt; &lt;br&gt; &lt;br&gt;En recientes días, los usuarios de CPAN de Perl han estado experimentando problemas para acceder hacia sus sitios, bases de datos ...
    </content>
    <category term="Noticias de Perl"/>
    <published>2010-02-07T08:56:43-05:00</published>
    <updated>2010-02-07T08:56:43-05:00</updated>
    <author>
      <name>Webmaster</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.perlhispano.com/cgi-bin/index.cgi?action=viewnews&amp;id=35</id>
  </entry>
  <entry>
    <title>Faster.pm のベンチ結果メモ</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100207/1265546096" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">今んとここんなかんじだ。ここまで恣意的な例だと、さすがに差がかなりでる。

tokuhirom@gpath% time FASTER_VERBOSE=1 perl -Mblib -MFaster -e 'sub calc { $s=1;$i=0;$s+=$i while 100000000&gt;($i+=1);print "$s\n"}; calc()'
optimising main
4999999950000001
FASTER_VERBOSE=1 perl -Mblib -MFaster -e   13.16s user 0.03s system 99% cpu 13.194 total
tokuhirom@gpath% time FASTER_VERBOSE=1 perl -e 'sub calc { $s=1;$i=0;$s+=$i while 100000000&gt;($i+=1);print "$s\n"}; calc()'
4999999950000001
FASTER_VERBOSE=1 perl -e   21.81s user 0.02s system 100% cpu 21.830 total</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>今んとここんなかんじだ。ここまで恣意的な例だと、さすがに差がかなりでる。</p>
<pre>
tokuhirom@gpath% time FASTER_VERBOSE=1 perl -Mblib -MFaster -e 'sub calc { $s=1;$i=0;$s+=$i while 100000000&gt;($i+=1);print "$s\n"}; calc()'
optimising main
4999999950000001
FASTER_VERBOSE=1 perl -Mblib -MFaster -e   13.16s user 0.03s system 99% cpu 13.194 total
tokuhirom@gpath% time FASTER_VERBOSE=1 perl -e 'sub calc { $s=1;$i=0;$s+=$i while 100000000&gt;($i+=1);print "$s\n"}; calc()'
4999999950000001
FASTER_VERBOSE=1 perl -e   21.81s user 0.02s system 100% cpu 21.830 total
</pre>

		</div>
</div>
    </content>
    <published>2010-02-07T21:34:56+09:00</published>
    <updated>2010-02-07T21:34:56+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100207/1265546096</id>
  </entry>
  <entry>
    <title>Writing games in Perl - Part 2 - Controlling the Ball</title>
    <link rel="alternate" href="http://daniel.ruoso.com/categoria/perl/games-perl-2" type="text/html"/>
    <summary type="text">Following the first post on the subject of writing games in Perl, where
we created a bouncing ball (I know, it is a rectangle, but I trust your
imagination), this post is going to add something very important when
dealing with games: input.

Silveira Neto suggested that I should include more specific instructions
on how to start the game (and maybe a video), so I recalled that I didn't
mention that all the sources for this posts (including the text) is
currently hosted at a github repository (if you plan to contribute,
please just ask me for commit permissions instead of forking the repo).

So if you want to run the codes posted here, you first need to:

$ git clone http://github.com/ruoso/games-perl.git

You can check for updates by calling

$ git pull origin master

from inside the games-perl directory. Each directory inside games-perl
starts with the number of the post. The first post is inside the
1-bouncing-ball directory and the second is in 2-controlling. To run the
the first code just get inside the first directory and call:

$ perl ball.pl

The second example code is based on the first, so the script name is the
same, so just get into the other directory and run the same line. If you
get an error like:

Can't locate SDL/Video.pm in @INC (@INC contains: /etc/perl
/usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10
/usr/local/lib/site_perl .) at ball.pl line 8.

It means you probably don't have the newest SDL, take a look at the first
post to see how to get the newest redesigned SDL.

Controlling the Ball

Enough for the introduction, let's get to the actual code. The first
thing we need is understanding SDL Events. If you ever programmed GUI
applications or even if you wrote some javascript you are aware of how an
event framework looks like. SDL is no exception, you need to wait (or
poll) for the events, and each event will contain the information you
need to figure out what happened.

In our case, we want to apply additional acceleration to the ball
whenever the arrow keys are pressed. But if we have an event-based
system, the way to figure out which of those four keys is currently
pressed is keeping a state mask and update it when you receive keydown
and keyup events.

So what we're going to do is to manipulate the acc_h and acc_v ball
attributes depending on the keydown and keyup events. It might look
complicated, but the only change we need is (this is inside ball.pl main
loop):

  while (SDL::Events::poll_event($event)) {
    if ($event-&gt;type == SDL_QUIT) {
      exit;

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_LEFT) {
      $ball-&gt;acc_h(-1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_LEFT) {
      $ball-&gt;acc_h(0);

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_RIGHT) {
      $ball-&gt;acc_h(1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_RIGHT) {
      $ball-&gt;acc_h(0);

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_UP) {
      $ball-&gt;acc_v(1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_UP) {
      $ball-&gt;acc_v(0);

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_DOWN) {
      $ball-&gt;acc_v(-1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_DOWN) {
      $ball-&gt;acc_v(0);

    }
  }

So, this is it. Follows a small video of the game.</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>Following <a href="http://daniel.ruoso.com/categoria/perl/games-perl-1">the first post</a> on the subject of writing games in Perl, where we created a bouncing ball (I know, it is a rectangle, but I trust your imagination), this post is going to add something very important when dealing with games: input. </p>
<p><a href="http://silveiraneto.net">Silveira Neto</a> suggested that I should include more specific instructions on how to start the game (and maybe a video), so I recalled that I didn't mention that all the sources for this posts (including the text) is currently hosted at a <a href="http://github.com/ruoso/games-perl">github repository</a> (if you plan to contribute, please just ask me for commit permissions instead of forking the repo). </p>
<p>So if you want to run the codes posted here, you first need to: <pre>
$ git clone http://github.com/ruoso/games-perl.git
</pre></p>
<p>You can check for updates by calling <pre>
$ git pull origin master
</pre></p>
<p>from inside the games-perl directory. Each directory inside games-perl starts with the number of the post. The first post is inside the <tt>1-bouncing-ball</tt> directory and the second is in <tt>2-controlling</tt>. To run the the first code just get inside the first directory and call: <pre>
$ perl ball.pl
</pre></p>
<p>The second example code is based on the first, so the script name is the same, so just get into the other directory and run the same line. If you get an error like: <pre>
Can't locate SDL/Video.pm in @INC (@INC contains: /etc/perl
/usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10
/usr/local/lib/site_perl .) at ball.pl line 8.
</pre></p>
<p>It means you probably don't have the newest SDL, take a look at the <a href="http://daniel.ruoso.com/categoria/perl/games-perl-1">first post</a> to see how to get the newest redesigned SDL. </p>
<h4>Controlling the Ball</h4>
<p>Enough for the introduction, let's get to the actual code. The first thing we need is understanding SDL Events. If you ever programmed GUI applications or even if you wrote some javascript you are aware of how an event framework looks like. SDL is no exception, you need to wait (or poll) for the events, and each event will contain the information you need to figure out what happened. </p>
<p>In our case, we want to apply additional acceleration to the ball whenever the arrow keys are pressed. But if we have an event-based system, the way to figure out which of those four keys is currently pressed is keeping a state mask and update it when you receive keydown and keyup events. </p>
<p>So what we're going to do is to manipulate the <tt>acc_h</tt> and <tt>acc_v</tt> ball attributes depending on the keydown and keyup events. It might look complicated, but the only change we need is (this is inside ball.pl main loop): <pre>
  while (SDL::Events::poll_event($event)) {
    if ($event-&gt;type == SDL_QUIT) {
      exit;

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_LEFT) {
      $ball-&gt;acc_h(-1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_LEFT) {
      $ball-&gt;acc_h(0);

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_RIGHT) {
      $ball-&gt;acc_h(1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_RIGHT) {
      $ball-&gt;acc_h(0);

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_UP) {
      $ball-&gt;acc_v(1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_UP) {
      $ball-&gt;acc_v(0);

    } elsif ($type == SDL_KEYDOWN &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_DOWN) {
      $ball-&gt;acc_v(-1);

    } elsif ($type == SDL_KEYUP &amp;&amp;
             $sevent-&gt;key_sym() == SDLK_DOWN) {
      $ball-&gt;acc_v(0);

    }
  }
</pre></p>
<p>So, this is it. Follows a small video of the game.<br/><br/><object height="344" width="425"><param name="movie" value="http://www.youtube.com/v/On8O7jJP_WI&amp;hl=pt_BR&amp;fs=1&amp;"/><param name="allowFullScreen" value="true"/><param name="allowscriptaccess" value="always"/><embed allowfullscreen="true" height="344" width="425"/></object></p>
</div>
    </content>
    <published>2010-02-07T10:30:30Z</published>
    <updated>2010-02-07T10:30:30Z</updated>
    <author>
      <name>nobody</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://daniel.ruoso.com/categoria/perl/games-perl-2</id>
  </entry>
  <entry>
    <title>New stuff in DBIx::Class::Helpers 2.00200</title>
    <link rel="alternate" href="http://blog.afoolishmanifesto.com/archives/1289" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">A new release of the resplendent Perl ORM DBIx::Class means new release
of DBIx::Class::Helpers

The ResultSet::Random helper had the wrong function used for MySQL. That
was fixed thanks to an RT from pldoh.

get_namespace_parts from the util package was unnecessarily strict.
Thanks to melo for the prodding to do that.

I refactored some of the code in core DBIx::Class so that I can more
easily detect is_numeric with Row::NumifyGet, instead of requiring the
user to specify it. Normally DBIx::Class autodetects it based on column
type, but that code wasn’t quite generic enough until now. Nice!

And then the most exciting bit is a new helper entirely for the suite:
Row::ToJSON. Basically I was sick of doing this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

package ACD::Schema::Result::Foo;

# regular package stuff here

sub TO_JSON {
my $self = shift;
return {
id =&gt; $self-&gt;id,
foo =&gt; $self-&gt;foo,
# etc etc ad nausium
}
}

"distraction";

Of course that can be shortened to:

1
2
3
4

sub TO_JSON {
my $self = shift;
return { map +( $_ =&gt; $self-&gt;$_), qw{id foo ...} }
}

But I still have to make that stupid columns list! This shiny new helper
makes a TO_JSON method that will simply include all of your columns
except for the “heavy” ones like TEXT, NTEXT, or BLOB. Of course you can
have finer-grained control than that by explicitly saying to include (or
not) a column in it’s configuration. See the docs for all the nitty
gritty details.


Related Posts:
--------------

  * Latest additions to DBIC::Helpers

  * New stuff in DBIx::Class::Helpers

  * Solution on how to serialize dates nicely

  * Paranoid Deletion in DBIx::Class

  * Do Passwords Right

  * Powered by Contextual Related Posts</div>
    </summary>
    <content type="html">&lt;p&gt;A new release of the resplendent &lt;a href="http://search.cpan.org/perldoc?DBIx::Class"&gt;Perl ORM&lt;/a&gt; &lt;a href="http://search.cpan.org/perldoc?DBIx::Class"&gt;DBIx::Class&lt;/a&gt; means new release of &lt;a href="http://search.cpan.org/perldoc?DBIx::Class::Helpers"&gt;DBIx::Class::Helpers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/ResultSet/Random.pm"&gt;ResultSet::Random helper&lt;/a&gt; had the wrong function used for MySQL.  That was fixed thanks to an RT from pldoh.&lt;/p&gt;
&lt;p&gt;get_namespace_parts from &lt;a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helpers/Util.pm"&gt;the util package&lt;/a&gt; was unnecessarily strict.  Thanks to melo for the prodding to do that.&lt;/p&gt;
&lt;p&gt;I refactored some of the code in core DBIx::Class so that I can more easily detect is_numeric with &lt;a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/Row/NumifyGet.pm"&gt;Row::NumifyGet&lt;/a&gt;, instead of requiring the user to specify it.  Normally DBIx::Class autodetects it based on column type, but that code wasn&amp;#8217;t quite generic enough until now.  Nice!&lt;/p&gt;
&lt;p&gt;And then the most exciting bit is a new helper entirely for the suite: &lt;a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/Row/ToJSON.pm"&gt;Row::ToJSON&lt;/a&gt;.  Basically I was sick of doing this:&lt;/p&gt;
&lt;div class="codecolorer-container perl vibrant"&gt;&lt;table cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class="perl codecolorer"&gt;&lt;a href="http://perldoc.perl.org/functions/package.html"&gt;&lt;span&gt;package&lt;/span&gt;&lt;/a&gt; ACD&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Schema&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Foo&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;# regular package stuff here&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;sub&lt;/span&gt; TO_JSON &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span&gt;my&lt;/span&gt; &lt;span&gt;$self&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;a href="http://perldoc.perl.org/functions/shift.html"&gt;&lt;span&gt;shift&lt;/span&gt;&lt;/a&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;a href="http://perldoc.perl.org/functions/return.html"&gt;&lt;span&gt;return&lt;/span&gt;&lt;/a&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; id &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;$self&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; foo &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;$self&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;foo&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span&gt;# etc etc ad nausium &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;&amp;quot;distraction&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Of course that can be shortened to:&lt;/p&gt;
&lt;div class="codecolorer-container perl vibrant"&gt;&lt;table cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class="perl codecolorer"&gt;&lt;span&gt;sub&lt;/span&gt; TO_JSON &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span&gt;my&lt;/span&gt; &lt;span&gt;$self&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;a href="http://perldoc.perl.org/functions/shift.html"&gt;&lt;span&gt;shift&lt;/span&gt;&lt;/a&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;a href="http://perldoc.perl.org/functions/return.html"&gt;&lt;span&gt;return&lt;/span&gt;&lt;/a&gt; &lt;span&gt;&amp;#123;&lt;/span&gt; &lt;a href="http://perldoc.perl.org/functions/map.html"&gt;&lt;span&gt;map&lt;/span&gt;&lt;/a&gt; &lt;span&gt;+&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt; &lt;span&gt;$_&lt;/span&gt; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;$self&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;$_&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;a href="http://perldoc.perl.org/functions/qw.html"&gt;&lt;span&gt;qw&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&amp;#123;&lt;/span&gt;id foo &lt;span&gt;...&lt;/span&gt;&lt;span&gt;&amp;#125;&lt;/span&gt; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;But I still have to make that stupid columns list!  This shiny new helper makes a TO_JSON method that will simply include all of your columns except for the &amp;#8220;heavy&amp;#8221; ones like TEXT, NTEXT, or BLOB.  Of course you can have finer-grained control than that by explicitly saying to include (or not) a column in it&amp;#8217;s configuration.  See &lt;a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/Row/ToJSON.pm"&gt;the docs&lt;/a&gt; for all the nitty gritty details.&lt;/p&gt;
&lt;div id="crp_related"&gt;&lt;h2&gt;Related Posts:&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1261" rel="bookmark" class="crp_title"&gt;Latest additions to DBIC::Helpers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1234" rel="bookmark" class="crp_title"&gt;New stuff in DBIx::Class::Helpers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1273" rel="bookmark" class="crp_title"&gt;Solution on how to serialize dates nicely&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/274" rel="bookmark" class="crp_title"&gt;Paranoid Deletion in DBIx::Class&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1286" rel="bookmark" class="crp_title"&gt;Do Passwords Right&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Powered by &lt;a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/"&gt;Contextual Related Posts&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</content>
    <category term="Uncategorized cpan dbix::class dbix::class::helpers perl"/>
    <published>2010-02-07T07:32:24Z</published>
    <updated>2010-02-07T07:32:24Z</updated>
    <author>
      <name>fREW Schmidt</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://blog.afoolishmanifesto.com/?p=1289</id>
  </entry>
  <entry>
    <title>[Perl]ホットスポットを最適化する</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/gfx/20100207/1265523020" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">最適化するのに相応しいサブルーチンのみ最適化できるように，optimizer::hotspotというモジュールを考えてみた。まだCPANクオリティではないのでgithubのみ。

  * http://github.com/gfx/Perl-optimizer-hotspot

仕組みとしては，PL_peeppをフックして，生成されるサブルーチンの頭にホットスポット計測のためのopcode*1を仕込み，そのopcodeが一定数呼ばれると，最適化器*2を起動するというものだ。

最適化の基本は，いまのところ特定パターンをもつ構文木を高速な一つのノードに置き換えるというもの。少し実装してみたところ，以下のような結果となった。

benchmarks/arbit.pl

# 's' represents 'single-threaded'
$ sperl -Mblib benchmarks/arbit.pl
Perl/5.10.1 on i686-linux
           Rate     plain optimized
plain     489/s        --      -39%
optimized 797/s       63%        --

以上，Perlを63%高速化することができた。

.

.

.

もちろん，これで済むほど話は簡単ではない。このベンチマークは恣意的なもので，ベンチマークスクリプトは非常に不自然なコードである。もう少しまともなbenchmark/math.plを実行すると，効果は誤差の範囲内でしかないことがわかる。

ホットスポットを検出して最適化器を起動する，というところまではいいが，そこから先の最適化についてはもう少しいい方法を考えないと使い物にならないのではないかと思う。

特定パターンを検出する方法は，まずパターンの検出が大変すぎるし，この調子でパターンを増やしたとしても所詮ヒューリスティクスによる小手先の最適化にすぎず，アプリケーションレベルで+10%達成できれば御の字だろう。

ということを考えると，プロファイラでボトルネックを探してその部分をXS化するほうがずっと簡単だ。

*1：対応するppcodeはoptimizer_pp_count()

*2：optimizer_hotspot_peep() -&gt; optimizer_combine_opcode()</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>最適化するのに相応しいサブルーチンのみ最適化できるように，optimizer::hotspotというモジュールを考えてみた。まだCPANクオリティではないのでgithubのみ。</p>
			<ul>
				<li> <a href="http://github.com/gfx/Perl-optimizer-hotspot">http://github.com/gfx/Perl-optimizer-hotspot</a></li>
			</ul>
			<p>仕組みとしては，PL_peeppをフックして，生成されるサブルーチンの頭にホットスポット計測のためのopcode<span class="footnote"><a href="/gfx/#f1" name="fn1" title="対応するppcodeはoptimizer_pp_count() ">*1</a></span>を仕込み，そのopcodeが一定数呼ばれると，最適化器<span class="footnote"><a href="/gfx/#f2" name="fn2" title="optimizer_hotspot_peep() -&gt; optimizer_combine_opcode() ">*2</a></span>を起動するというものだ。</p>
			<p>最適化の基本は，いまのところ特定パターンをもつ構文木を高速な一つのノードに置き換えるというもの。少し実装してみたところ，以下のような結果となった。</p>
			<p><a href="http://github.com/gfx/Perl-optimizer-hotspot/blob/master/benchmarks/arbit.pl">benchmarks/arbit.pl</a></p>
<pre>
# 's' represents 'single-threaded'
$ sperl -Mblib benchmarks/arbit.pl
Perl/5.10.1 on i686-linux
           Rate     plain optimized
plain     489/s        --      -39%
optimized 797/s       63%        --
</pre>

			<p>以上，Perlを63%高速化することができた。</p>
			<p>.</p>
			<p>.</p>
			<p>.</p>
			<p>もちろん，これで済むほど話は簡単ではない。このベンチマークは恣意的なもので，ベンチマークスクリプトは非常に不自然なコードである。もう少しまともなbenchmark/math.plを実行すると，効果は誤差の範囲内でしかないことがわかる。</p>
			<p>ホットスポットを検出して最適化器を起動する，というところまではいいが，そこから先の最適化についてはもう少しいい方法を考えないと使い物にならないのではないかと思う。</p>
			<p>特定パターンを検出する方法は，まずパターンの検出が大変すぎるし，この調子でパターンを増やしたとしても所詮ヒューリスティクスによる小手先の最適化にすぎず，アプリケーションレベルで+10%達成できれば御の字だろう。</p>
			<p>ということを考えると，プロファイラでボトルネックを探してその部分をXS化するほうがずっと簡単だ。</p>
		</div>
		<div class="footnote">
			<p class="footnote"><a href="/gfx/#fn1" name="f1">*1</a>：対応するppcodeはoptimizer_pp_count() </p>
			<p class="footnote"><a href="/gfx/#fn2" name="f2">*2</a>：optimizer_hotspot_peep() -&gt; optimizer_combine_opcode() </p>
		</div>
</div>
    </content>
    <category term="Perl"/>
    <published>2010-02-07T15:10:20+09:00</published>
    <updated>2010-02-07T15:10:20+09:00</updated>
    <author>
      <name>gfx</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/gfx/20100207/1265523020</id>
  </entry>
  <entry>
    <title>Its not kept behind the scullery maid under an aarvark</title>
    <link rel="alternate" href="http://use.perl.org/~redspike/journal/40162?from=rss" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">How to learn how to get help in Perl

I made a great discovery today but it has taken me a few years to get to
it. I have wondered why it has been so hard to get into the shiny ball
that surrounds some of the programming languages. This is not just Perl
but many of them. I started to compare the way I learn text editors with
the way I have learned programming languages. Vi was the first real
editor I decided to learn.

  1. Started it at the command line

  2. Wondered how the hell I opened a file

  3. Wondered how the hell I closed a file

  4. Wondered how the hell I edited it

  5. Wondered what all the fuss was about

  6. I then bought a book and read it

  7. Understood somethings and not others

  8. Discovered how powerful it was and realised what all the fuss was
    about

  9. Flirted with the idea of using it all the time

  10. Found I could use it to do something I needed to do

  11. Discovered how to use the help files

  12. Understood what to do with a file and to do something useful that I
    could do however small

  13. Used it infrequently when I had to during an ssh session on a
    server or just played with it

  14. One day decided to use it all the time and be damned

  15. It took a bit of working out and the first project I did with it
    took at least twice as long as normal

  16. Now I use it all the time except when I am using Emacs in fact I
    cannot imagine life without it

So what is the difference with programming? Well I thought there would
not be too much after all people have said 'if you can use Vi you can
program'. So here we go with Perl.

  1. Started it at the command line

  2. Wondered how the hell I created a variable

  3. Wondered what the hell I did with a variable once I had one

  4. Wondered how the hell made anything do anything to do anything

  5. Wondered what all the fuss was about

  6. I then bought a book and read it

  7. Understood somethings and not others

  8. Discovered how powerful it was and realised what all the fuss was
    about

  9. Flirted with the idea of using it all the time

  10. Found I could use it to do something I needed to do

  11. Null

  12. Null

  13. Used it for a few scripts which help with some very basic cgi stuff

  14. Would liked to have used it for lots of things but could not work
    out how

  15. Became frustrated because it seemed like a shiney ball that I could
    not get into

  16. I do not use it every day to do stuff

The big difference which is glaringly obvious now, but I had not seen
before is the help system and understanding something I could do that was
useful.

I came to this conclusion from the other end of the stick by trying to
see where I was falling down and why I could not dash a script off when I
needed to do something. I knew that if I was to use it to achieve the
programming goals I needed to use it frequently to be able to progress
onto larger programs that I have in mind.

It came to the fact that I could not remember things sometimes. I related
this to my Vi experience and realised that I had had the same sort of
problem but that had not stopped me from using it everyday. The
difference was that it was so hard to get help from the help system. In
fact I had been using the web for quick howtos and stuff had made it
harder as it was a second hand help system in a way, it was not from the
guts if you like.

I was walking around the office talking to myself and gesticulating a
pieces of paper and trying to see how I could get the kind of help from
Perl than I did from :h in Vi.

Of course its perldoc and man perlmodlib. I had played around with it but
at no point had any book walked me through the way to use it. I sort of
bumbled through and got by the best I could by using books and search
engines. While learning any program like vi, emacs or Open Office the
help files are there and most are accessible from a help menu or command.
Books are bought and read and understood and exercises accomplished. When
I forget something I can look it up in the help files, I do it without
thinking. So once you learn one program and read some books, you know
that there will be a help system to hold your hand when you need it. The
book is part of the help system in a way but it is never implied it is
just there and assumed that it will be used.

Switching to learning a programming language the same is not true there
is not a system called help. In Java there are loads of documentation and
tons of libraries of classes to wade through. In Perl there is perdoc.
These two are alluded to but not really explained. You get instructions
like 'There are thousands of libraries to get to do all the things you
want to do without writing code' or 'There is always perldoc to help you
out and thousands of modules'. Similar direction are found in program
books referring to the help system, but everyone knows about help systems
its there in the culture of using a program.

Once I looked at the similarities and differences in learning programming
and learning a program and treated them the same it dawned on me that you
all out there must be able to find stuff in perldoc that I am missing. So
I knew I had to find a way to get what I wanted to know out of the Perl
Help System. I looked on the net and looked in books for the bit that I
was missing. I got to perldoc but it did not tell me everything. I askerd
on IRC where was the list of stuff on Perl that is on the perldoc website
and I got the answer. Perldoc perl or perldoc perltoc. WHY IS IT NOT THE
FIRST CHAPTER IN ANY PROGRAMMING BOOK OR ON THE FIRST PAGE OF A WEBSITE
THAT EXPLAINS HOW TO FIND OUT WHAT YOU WANT TO KNOW? I found it but it
has taken me ages to find it. I new it was there but did not know how to
access it. If there are books out there that do explain this then I am
sorry that I have not read it or perhaps I missed that chapter.

'man perlmodlib' to see what the core modules are

'perldoc -f insert-function-name'

'perldoc perl' for a summary list of functions, other perldoc pages and
loads of other stuff. Decide what you want to look up and type perldoc
perlref for stuff on perl references - easy huh

'perldoc perltoc' for a an in depth look at everything in Perl

This is the entrance to Perl, not the back door to be found behind the
scullery maid under an aardvark when every other avenue has been
exhausted

Given this revelation on how to find what I wanted to find I took up the
editor of choice and started a very simple script. when I got to
something that did not compile and I could not figure out why it
wouldn't, I could, with confidence go to the 'help system' and find the
right syntax etc.

It then smacked me in the face, I may be wrong but there does not seem to
be the same thing in any other system, it may be close but not the same.
So why wasn't the 'perldoc how to program like you a have never
programmed before even if you have never programmed' message out there. A
healthy language needs new recruits and helping them find what and how
they can achieve what they want to do is paramount in keeping those new
recruits and keeping the language alive. Maybe it is presumed that
programmers who are familiar with such things will always read
programming books/articles/blogs. Well nobody is born with innate
knowledge of a system, they have to learn it and the first thing is to
learn how to get help. To a complete novice it is the most important
thing to be able to help themselves to help themselves.

Perldoc is not documentation, yes I know they are documents, it is the
help system, and it is there on your machine tailored to the version
installed on your machine. It is easy to access anywhere where there is
Perl installed - your friend in a box. How cool is that?</div>
    </summary>
    <content type="html">&lt;p&gt; &lt;b&gt;How to learn how to get help in Perl &lt;/b&gt; &lt;/p&gt;&lt;p&gt;I made a great discovery today but it has taken me a few years to get to it. I have wondered why it has been so hard to get into the shiny ball that surrounds some of the programming languages. This is not just Perl but many of them. I started to compare the way I learn text editors with the way I have learned programming languages. Vi was the first real editor I decided to learn.&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Started it at the command line&lt;/li&gt;&lt;li&gt;Wondered how the hell I opened a file&lt;/li&gt;&lt;li&gt;Wondered how the hell I closed a file&lt;/li&gt;&lt;li&gt;Wondered how the hell I edited it&lt;/li&gt;&lt;li&gt;Wondered what all the fuss was about&lt;/li&gt;&lt;li&gt;I then bought a book and read it&lt;/li&gt;&lt;li&gt;Understood somethings and not others&lt;/li&gt;&lt;li&gt;Discovered how powerful it was and realised what all the fuss was about&lt;/li&gt;&lt;li&gt;Flirted with the idea of using it all the time&lt;/li&gt;&lt;li&gt;Found I  could use it to do something I  needed to do&lt;/li&gt;&lt;li&gt;Discovered how to use the help files&lt;/li&gt;&lt;li&gt;Understood what to do with a file and to do something useful that I could do however small&lt;/li&gt;&lt;li&gt;Used it infrequently when I had to during an ssh session on a server or just played with it&lt;/li&gt;&lt;li&gt;One day decided to use it all the time and be damned&lt;/li&gt;&lt;li&gt;It took a bit of working out and the first project I did with it took at least twice as long as normal&lt;/li&gt;&lt;li&gt;Now I use it all the time except when I am using Emacs in fact I cannot imagine life without it&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So what is the difference with programming? Well I thought there would not be too much after all people have said 'if you can use Vi you can program'. So here we go with Perl.&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Started it at the command line&lt;/li&gt;&lt;li&gt;Wondered how the hell I created a variable&lt;/li&gt;&lt;li&gt;Wondered what the hell I did with a variable once I had one&lt;/li&gt;&lt;li&gt;Wondered how the hell made anything do anything to do anything&lt;/li&gt;&lt;li&gt;Wondered what all the fuss was about&lt;/li&gt;&lt;li&gt;I then bought a book and read it&lt;/li&gt;&lt;li&gt;Understood somethings and not others&lt;/li&gt;&lt;li&gt;Discovered how powerful it was and realised what all the fuss was about&lt;/li&gt;&lt;li&gt;Flirted with the idea of using it all the time&lt;/li&gt;&lt;li&gt;Found I could use it to do something I needed to do&lt;/li&gt;&lt;li&gt;Null&lt;/li&gt;&lt;li&gt;Null&lt;/li&gt;&lt;li&gt;Used it for a few scripts which help with some very basic cgi stuff&lt;/li&gt;&lt;li&gt;Would liked to have used it for lots of things but could not work out how&lt;/li&gt;&lt;li&gt;Became frustrated because it seemed like a shiney ball that I could not get into&lt;/li&gt;&lt;li&gt;I do not use it every day to do stuff&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The big difference which is glaringly obvious now, but I had not seen before is the  &lt;b&gt;help system&lt;/b&gt; and &lt;b&gt;understanding something I could do that was useful.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I came to this conclusion from the other end of the stick by trying to see where I was falling down and why I could not dash a script off when I needed to do something. I knew that if I was to use it to achieve the programming goals I needed to use it frequently to be able to progress onto larger programs that I have in mind.&lt;/p&gt;&lt;p&gt;It came to the fact that I could not remember things sometimes. I related this to my Vi experience and realised that I had had the same sort of problem but that had not stopped me from using it everyday. The difference was that it was so hard to get help from the help system. In fact I had been using the web for quick howtos and stuff had made it harder as it was a second hand help system in a way, it was not from the guts if you like.&lt;/p&gt;&lt;p&gt;I was walking around the office talking to myself and gesticulating a pieces of paper and trying to see how I could get the kind of help from Perl than I did from&lt;nobr&gt; &lt;wbr&gt;&lt;/nobr&gt;:h in Vi.&lt;/p&gt;&lt;p&gt;Of course its perldoc and man perlmodlib. I had played around with it but at no point had any book walked me through the way to use it. I sort of bumbled through and got by the best I could by using books and search engines. While learning any program like vi, emacs or Open Office the help files are there and most are accessible from a help menu or command. Books are bought and read and understood and exercises accomplished. When I forget something I can look it up in the help files, I do it without thinking. So once you learn one program and read some books, you know that there will be a help system to hold your hand when you need it. The book is part of the help system in a way but it is never implied it is just there and assumed that it will be used.&lt;/p&gt;&lt;p&gt;Switching to learning a programming language the same is not true there is not a system called help. In Java there are loads of documentation and tons of libraries of classes to wade through. In Perl there is perdoc. These two are alluded to but not really explained. You get instructions like 'There are thousands of libraries to get to do all the things you want to do without writing code' or 'There is always perldoc to help you out and thousands of modules'. Similar direction are found in program books referring to the help system, but everyone knows about help systems its there in the culture of using a program. &lt;/p&gt;&lt;p&gt;Once I looked at the similarities and differences in learning programming and learning a program and treated them the same it dawned on me that you all out there must be able to find stuff in perldoc that I am missing. So I knew I had to find a way to get what I wanted to know out of the Perl Help System. I looked on the net and looked in books for the bit that I was missing. I got to perldoc but it did not tell me everything. I askerd on IRC where was the list of stuff on Perl that is on the perldoc website and I got the answer. Perldoc perl or perldoc perltoc. WHY IS IT NOT THE FIRST CHAPTER IN ANY PROGRAMMING BOOK OR ON THE FIRST PAGE OF A WEBSITE THAT EXPLAINS HOW TO FIND OUT WHAT YOU WANT TO KNOW? I found it but it has taken me ages to find it. I new it was there but did not know how to access it. If there are books out there that do explain this then I am sorry that I have not read it or perhaps I missed that chapter. &lt;/p&gt;&lt;p&gt; &lt;b&gt;'man perlmodlib' to see what the core modules are&lt;/b&gt; &lt;/p&gt;&lt;p&gt; &lt;b&gt;'perldoc -f insert-function-name'&lt;/b&gt; &lt;/p&gt;&lt;p&gt; &lt;b&gt;'perldoc perl' for a summary list of functions, other perldoc pages and loads of other stuff. Decide what you want to look up and type perldoc perlref for stuff on perl references - easy huh&lt;/b&gt; &lt;/p&gt;&lt;p&gt; &lt;b&gt;'perldoc perltoc' for a an in depth look at everything in Perl&lt;/b&gt; &lt;/p&gt;&lt;p&gt;This is the entrance to Perl, not the back door to be found behind the scullery maid under an aardvark when every other avenue has been exhausted&lt;/p&gt;&lt;p&gt;Given this revelation on how to find what I wanted to find I took up the editor of choice and started a very simple script. when I got to something that did not compile and I could not figure out why it wouldn't, I could, with confidence go to the 'help system' and find the right syntax etc.&lt;/p&gt;&lt;p&gt;It then smacked me in the face, I may be wrong but there does not seem to be the same thing in any other system, it may be close but not the same. So why wasn't the 'perldoc how to program like you a have never programmed before even if you have never programmed' message out there. A healthy language needs new recruits and helping them find what and how they can achieve what they want to do is paramount in keeping those new recruits and keeping the language alive. Maybe it is presumed that programmers who are familiar with such things will always read programming books/articles/blogs. Well nobody is born with innate knowledge of a system, they have to learn it and the first thing is to learn how to get help. To a complete novice it is the most important thing to be able to help themselves to help themselves.&lt;/p&gt;&lt;p&gt;Perldoc is not documentation, yes I know they are documents, it is the help system, and it is there on your machine tailored to the version installed on your machine. It is easy to access anywhere where there is Perl installed - your friend in a box. How cool is that?&lt;/p&gt;</content>
    <category term="journal"/>
    <published>2010-02-06T22:52:51Z</published>
    <updated>2010-02-06T22:52:51Z</updated>
    <author>
      <name>redspike</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://use.perl.org/~redspike/journal/40162?from=rss</id>
  </entry>
  <entry>
    <title>Contributing to CPAN: PAUSE Id, Bug Tracking, and Code Repositories</title>
    <link rel="alternate" href="http://babyl.dyndns.org/techblog/2010/02/contributing-to-cpan-pause-id-bug-tracking-and-code-repositories.html" type="text/html"/>
    <summary type="text">originally published on the Pythian blog.

CPAN Wants You!

Want to contribute to your favorite CPAN module, or maybe create your
own, but don't have the foggiest idea how to do it? Here are a few notes,
tips, tricks, and links that might help you get started.


PAUSE id
--------

While bringing awesome street cred, having a PAUSE id is strictly
necessary only if you want to maintain or co-maintain a module. If you
just want to contribute code, you'll perfectly be able to do without, as
it will usually be done via patches submitted to a bug tracking system, a
code repository or using good ol' email.


Becoming a co-maintainer

Becoming the co-maintainer of a module gives you the power to upload
authorized releases of the modules on CPAN. To become one, the maintainer
of the module simply has to promote you as such on PAUSE.


Creating a new module

You want to create your own module? Excellent! But before you do it, make
sure that you

  *  verified on CPAN that there's not already a module that already
    scratch that particular itch.

  * made sure that the module uses a descriptive and pertinent namespace.

Once this is done, go ahead: log on PAUSE and register the module.


Adopting an abandoned module

There's a module apparently abandoned by its owner that you'd love to
take over? The procedure for that is given in the CPAN FAQ, and it can be
boiled down to:

  * Try to get in contact with the current maintainer.

  * If you reach him or her, make puppy eyes and ask if you can take
    over.

  * If they are agreeable, they will flip over the maintenance of the
    module to you on PAUSE, and that's all there is to it.

  * If you tried their email addresses, poked around in mailing lists,
    forums and other places without any luck, wait a little bit (a couple
    of weeks) and contact the PAUSE admins.


Module created! How do I upload releases, now?

You upload new versions of a module via the PAUSE interface or via ftp.

Alternatively, and more conveniently, you can also use the cpan-upload
script provided by CPAN::Uploader.


Bug Tracking
------------

Contributing to a module means fixing bugs or implementing new
enhancements. To find those, who are you gonna call? The Bug Tracker!


rt.cpan.org

By default, every module on CPAN has a bug tracking queue on rt.cpan.org.
For example, the one for Git::CPAN::Patch is at
http://rt.cpan.org/Public/Dist/Display.html?Name=Git-CPAN-Patch.

Bug reporting can be done via the web interface, or by sending an email
to bug-module@rt.cpan.org (e.g., bug-git-cpan-patch@rt.cpan.org).


...or somewhere else

Sometimes, the module's maintainer uses a different bug tracking system.
You'll typically find it mentioned in the POD, or in the META.yml:

$ curl -L http://search.cpan.org/dist/Git-CPAN-Patch/META.yml | \
  perl -MYAML -0 -E'say Load(&lt;&gt;)-&gt;{resources}{bugtracker}'

http://rt.cpan.org/NoAuth/Bugs.html?Dist=Git-CPAN-Patch

If you don't feel inclined to dig into META.yml for information, there is
a Greasemonkey script that will do it for you, and automatically add a
link to the bugtracker (along some other goodies) on the module's CPAN
page.


...or here, there and everywhere

What if the bugs are kept on rt.cpan.org, and on the local bug tracking
system of Github, and a few other places? You can either follow them
manually, or you can get funky and experiment with SD, a peer-to-peer
ticket tracking system that can sync with and merge the information of
several online bug tracking systems. SD, it goes without saying, can be
found on CPAN as App::SD.


Code Repository
---------------

Most, but not all, modules have a public code repository somewhere out
there. Just like for the bug tracking system look for it in the POD, or
in the META.yml. It will be displayed on the module's cpan page as well.

$ curl -L http://search.cpan.org/dist/Git-CPAN-Patch/META.yml | \
    perl -MYAML -0 -E'say Load(&lt;&gt;)-&gt;{resources}{repository}'

git://github.com/yanick/git-cpan-patch.git


&lt;singing name="Adam West"&gt;Na na na na, Na na na na, GitPAN!&lt;/singing&gt;

Thanks to Schwern, all CPAN distributions now have a GitHub repository
tracking its releases. They can all be found under the GitHub gitpan
account, and follow the pattern http://github.com/gitpan/Git-CPAN-Patch.


Git::CPAN::Patch

Speaking of Git::CPAN::Patch, you can use its set of scripts to ease the
creation of CPAN-related git repositories. It also includes scripts to
send patches directly from your local repository to a rt bug queue.</summary>
    <content type="html">
        &lt;p&gt;&lt;i&gt;originally published on the 
&lt;a href="http://www.pythian.com/news/7877/contributing-to-cpan-pause-id-bug-tracking-and-code-repositories/"&gt;Pythian blog&lt;/a&gt;.&lt;/i&gt;&lt;/p&gt;

&lt;div&gt;&lt;img alt="CPAN Wants You!" src="http://www.pythian.com/news/wp-content/uploads/cpan-wants-you.jpg"&gt;&lt;/div&gt;

&lt;p&gt;Want to contribute to your favorite CPAN module, or maybe create your own, but don't have the foggiest idea how to do it?  Here are a few notes, tips, tricks, and links that might help you get started.&lt;/p&gt;

&lt;h2&gt;PAUSE id&lt;/h2&gt;
&lt;p&gt;While bringing awesome street cred, having a &lt;a href="http://pause.perl.org/pause/query?ACTION=request_id"&gt;PAUSE id&lt;/a&gt; is strictly necessary only if you want to maintain or co-maintain a module.  If you just want to contribute code, you'll perfectly be able to do without, as it will usually be done via patches submitted to a bug tracking system, a code repository or using good ol' email.&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;Becoming a co-maintainer&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;Becoming the co-maintainer of a module gives you the power to upload authorized releases of the modules on CPAN.  To become one, the maintainer of the module simply has to promote you as such on PAUSE.&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;Creating a new module&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;You want to create your own module?  Excellent!  But before you do it, make sure that you&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; verified on &lt;a href="http://search.cpan.org"&gt;CPAN&lt;/a&gt; that there's not already a module that already scratch that particular itch.&lt;/li&gt;
&lt;li&gt;made sure that the module uses a &lt;a href="http://pause.perl.org/pause/query?ACTION=pause_namingmodules"&gt;descriptive and pertinent namespace&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once this is done, go ahead: log on &lt;a href="http://pause.cpan.org"&gt;PAUSE&lt;/a&gt; and &lt;a href="https://pause.perl.org/pause/authenquery?ACTION=apply_mod"&gt;register the module&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;Adopting an abandoned module&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;There's a module apparently abandoned by its owner that you'd love to take over?  The procedure for that is given in the &lt;a href="http://www.cpan.org/misc/cpan-faq.html#How_adopt_module"&gt;CPAN FAQ&lt;/a&gt;, and it can be boiled down to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Try to get in contact with the current maintainer.&lt;/li&gt;
&lt;li&gt;If you reach him or her, make puppy eyes and ask if you can take over.&lt;/li&gt;
&lt;li&gt;If they are agreeable, they will flip over the maintenance of the module to you on PAUSE, and that's all there is to it.&lt;/li&gt;
&lt;li&gt;If you tried their email addresses, poked around in mailing lists, forums and other places without any luck, wait a little bit (a couple of weeks) and contact the PAUSE admins.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;i&gt;Module created! How do I upload releases, now?&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;You upload new versions of a module via the &lt;a href="https://pause.perl.org/pause/authenquery?ACTION=add_uri"&gt;PAUSE interface&lt;/a&gt; or via ftp.&lt;/p&gt;
&lt;p&gt;Alternatively, and more conveniently, you can also use the &lt;code&gt;cpan-upload&lt;/code&gt; script provided by &lt;a href="http://search.cpan.org/~rjbs/CPAN-Uploader"&gt;CPAN::Uploader&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Bug Tracking&lt;/h2&gt;
&lt;p&gt;Contributing to a module means fixing bugs or implementing new enhancements.  To find those, who are you gonna call? The Bug Tracker!&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;rt.cpan.org&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;By default, every module on CPAN has a bug tracking queue on &lt;a href="//rt.cpan.org"&gt;rt.cpan.org&lt;/a&gt;. For example, the one for Git::CPAN::Patch is at &lt;a href="http://rt.cpan.org/Public/Dist/Display.html?Name=Git-CPAN-Patch"&gt;http://rt.cpan.org/Public/Dist/Display.html?Name=Git-CPAN-Patch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bug reporting can be done via the web interface, or by sending an email to &lt;code&gt;bug-&lt;em&gt;module&lt;/em&gt;@rt.cpan.org&lt;/code&gt; (e.g., &lt;code&gt;bug-git-cpan-patch@rt.cpan.org&lt;/code&gt;).&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;...or somewhere else&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;Sometimes, the module's maintainer uses a different bug tracking system.  You'll typically find it mentioned in the POD, or in the &lt;code&gt;META.yml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
$ curl -L http://search.cpan.org/dist/Git-CPAN-Patch/META.yml | \
  perl -MYAML -0 -E'say Load(&amp;lt;&amp;gt;)-&amp;gt;{resources}{bugtracker}'

http://rt.cpan.org/NoAuth/Bugs.html?Dist=Git-CPAN-Patch
&lt;/pre&gt;

&lt;p&gt;If you don't feel inclined to dig into &lt;code&gt;META.yml&lt;/code&gt; for information, there is a &lt;a href="http://userscripts.org/scripts/show/31748"&gt;Greasemonkey script&lt;/a&gt; that will do it for you, and automatically add a link to the bugtracker (along some other goodies) on the module's CPAN page.&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;...or here, there and everywhere&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;What if the bugs are kept on rt.cpan.org, and on the local bug tracking system of Github, and a few other places?  You can either follow them manually, or you can get funky and experiment with &lt;a href="http://syncwith.us/sd/using"&gt;SD&lt;/a&gt;, a peer-to-peer ticket tracking system that can sync with and merge the information of several online bug tracking systems.  SD, it goes without saying, can be found on CPAN as &lt;a href="http://search.cpan.org/dist/App-SD"&gt;App::SD&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Code Repository&lt;/h2&gt;
&lt;p&gt;Most, but not all, modules have a public code repository somewhere out there.  Just like for the bug tracking system look for it in the POD, or in the &lt;code&gt;META.yml&lt;/code&gt;.  It will be displayed on the module's cpan page as well.&lt;/p&gt;
&lt;pre&gt;
$ curl -L http://search.cpan.org/dist/Git-CPAN-Patch/META.yml | \
    perl -MYAML -0 -E'say Load(&amp;lt;&amp;gt;)-&amp;gt;{resources}{repository}'

git://github.com/yanick/git-cpan-patch.git
&lt;/pre&gt;
&lt;h3&gt;&lt;i&gt;&amp;lt;singing name="Adam West"&amp;gt;Na na na na, Na na na na, GitPAN!&amp;lt;/singing&amp;gt;&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;Thanks to &lt;a href="http://github.com/schwern/gitpan"&gt;Schwern&lt;/a&gt;, all CPAN distributions now have a &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; repository tracking its releases.  They can all be found under the GitHub &lt;a href="http://github.com/gitpan"&gt;gitpan account&lt;/a&gt;, and follow the pattern &lt;a href="http://github.com/gitpan/Git-CPAN-Patch"&gt;http://github.com/gitpan/Git-CPAN-Patch&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;i&gt;Git::CPAN::Patch&lt;/i&gt;&lt;/h3&gt;
&lt;p&gt;Speaking of &lt;a href="http://search.cpan.org/dist/Git-CPAN-Patch"&gt;Git::CPAN::Patch&lt;/a&gt;, you can use its set of scripts to ease the creation of CPAN-related git repositories.  It also includes scripts to send patches directly from your local repository to a rt bug queue. &lt;/p&gt;
			
        
    </content>
    <category term="perl cpan"/>
    <published>2010-02-06T18:04:33Z</published>
    <updated>2010-02-06T18:04:33Z</updated>
    <author>
      <name>Yanick</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:babyl.dyndns.org,2010:/techblog//1.174</id>
  </entry>
  <entry>
    <title>Pittsburgh Snowpocalypse</title>
    <link rel="alternate" href="http://martian.org/karen/2010/02/06/pittsburgh-snowpocalypse/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I’ve just looked out the window and there are two people using
cross-country skies to make their way up the street. Apparently there is
2 and a half feet of snow outside. I say “apparently” as there is no way
I’m going out there to find out.

The worry though is that I do need to go out tomorrow morning. I have a
flight to catch to New York and I’m hoping that the weather improves so
that the airport can open again. I really don’t want to miss my flight
home on Monday as it will be such hassle finding another flight.

When I first arranged this trip I had planned to go to the Perl
conference that is on at the minute in Minneapolis. A few weeks ago I
changed my mind because I was worried that the weather would be too bad…

Snowy Weather

Snowy Weather</div>
    </summary>
    <content type="html">&lt;p&gt;I&amp;#8217;ve just looked out the window and there are two people using cross-country skies to make their way up the street.  Apparently there is 2 and a half feet of snow outside.  I say &amp;#8220;apparently&amp;#8221; as there is no way I&amp;#8217;m going out there to find out.&lt;/p&gt;
&lt;p&gt;The worry though is that I do need to go out tomorrow morning.  I have a flight to catch to New York and I&amp;#8217;m hoping that the weather improves so that the airport can open again.  I really don&amp;#8217;t want to miss my flight home on Monday as it will be such hassle finding another flight.&lt;/p&gt;
&lt;p&gt;When I first arranged this trip I had planned to go to the &lt;a href="http://www.frozen-perl.org/mpw2010/"&gt;Perl conference&lt;/a&gt; that is on at the minute in Minneapolis.  A few weeks ago I changed my  mind because I was worried that the weather would be too bad&amp;#8230;&lt;/p&gt;
&lt;div id="attachment_1966" class="wp-caption alignnone"&gt;&lt;a href="http://martian.org/karen/wp-content/uploads/2010/02/IMG_4069.JPG"&gt;&lt;img src="http://martian.org/karen/wp-content/uploads/2010/02/IMG_4069-300x200.jpg" alt="Snowy Weather"&gt;&lt;/a&gt;&lt;p class="wp-caption-text"&gt;Snowy Weather&lt;/p&gt;&lt;/div&gt;
</content>
    <category term="America Perl Travel"/>
    <published>0</published>
    <updated>0</updated>
    <author>
      <name>karen</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://martian.org/karen/?p=1965</id>
  </entry>
  <entry>
    <title>...so complex that you need a large IDE to comprehend it</title>
    <link rel="alternate" href="http://headrattle.blogspot.com/2010/02/so-complex-that-you-need-large-ide-to.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">This is an excerpt from an Omaha.pm thread today.

We're discussing Eliminating Inheritance Via Smalltalk-Style Traits by
Curtis "Ovid" Poe.

  In his paper, Curtis wrote:
  Anyone forced to use "vi" (not even "vim") while trying to create an
  emergency patch of broken code over a slow telnet connection at 2:30
  in the morning is going to get very irritated if your codebase is so
  complex that you need a large IDE to comprehend it.



  Trey wrote:
  That is kind of silly. If you're shop is using IDE and developing
  under that sort of framework, your support people should be familiar
  with the code and the methods used to program it/maintain it.



Agreed. And have the capacity to perform emergency maintenance remotely
via whatever means are necessary to do so.

I don't think he's arguing that slow Internet connections are a good
idea. I think he's saying they happen.

  Trey wrote:
  That's sort of like saying that somebody is going to be irritated
  because they can't stoke up a hydroelectric plant with bellows...So
  what??



I love your analogy. :) So what? So your business is losing money in the
scenario he describes.

I see this an indictment of relying too heavily on fancy developer tools
to gloss over crappy code. If my code sucks in text form, but when I
right-click on it a million lines of code in my IDE jumps to my rescue
and explains it to me in pretty colors, then I'm helpless without that
IDE. That sounds like a bad idea.

In the stack of technology ignorance and dependency I've planted my flag
here:

- I don't really know or care about sub-atomic particles.
- I don't really know or care how electrons flow through conductors.
- I don't really know or care about chip design.
- I don't really know or care how hard drives, memory, and monitors
actually work.
- I don't really know or care how the Linux kernel works.
- I don't really know or care how perl is written (in C).
- I don't really know or care how most of perl's core packages work (in
Perl/XS/C).
- I don't really know deeply or care how most of the CPAN modules I use
work (in Perl/XS/C).
- I know EXACTLY how the text of the Perl I wrote works. I do recursive
grep's through text files to find out anything I need to know.
- Syntax highlighting is a crutch for the weak.
- Method auto-discovery is a crutch for the weak.
- Per-keystroke debugging is a crutch for the weak.
- Re-runnable images of crashes are a crutch for the weak.
- All that other fancy crap in your IDE is fancy crap I don't need. For
the weak. :)

Objectively, my gut-opinions about exactly where that line is are silly.
Aren't they?

If you take me and my Apple laptop running Terminal.app to ssh into a
server and run vi, and next to me you sit a .NET guy running the latest
Visual Studio on a mapped drive; is the total complexity of my dependency
stack much smaller than his? (OS X is how many millions of lines of
code?)

I don't know. I've now spent an hour arguing with myself about it. :)

In any event, I don't thing it's the use or avoidance of an IDE that
makes good or poor code. You can create beautiful or ugly code with the
simplest or fanciest of tools.

I do think he has a point. If your "...codebase is so complex that you
need a large IDE to comprehend it." Then you're doing something wrong.
Use an IDE because you want to, not because it's impossible to survive
your mess without it.

/me shakes his fist at XML Spy addicts

Ponder,

j</div>
    </summary>
    <content type="text">This is an excerpt from an &lt;a href="http://mail.pm.org/pipermail/omaha-pm/2010-February/002341.html"&gt;Omaha.pm thread&lt;/a&gt; today.&lt;br /&gt;&lt;br /&gt;We're discussing &lt;a href="http://www.slideshare.net/Ovid/inheritance-versus-roles-1799996"&gt;Eliminating Inheritance Via Smalltalk-Style Traits&lt;/a&gt; by Curtis "Ovid" Poe.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;In his paper, Curtis wrote:&lt;br&gt;Anyone forced to use "vi" (not even "vim") while trying to create an emergency patch of broken code over a slow telnet connection at 2:30 in the morning is going to get very irritated if your codebase is so complex that you need a large IDE to comprehend it.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Trey wrote:&lt;br&gt;That is kind of silly.  If you're shop is using IDE and developing under that sort of framework, your support people should be familiar with the code and the methods used to program it/maintain it.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Agreed. And have the capacity to perform emergency maintenance remotely via whatever means are necessary to do so.&lt;br /&gt;&lt;br /&gt;I don't think he's arguing that slow Internet connections are a good idea. I think he's saying they happen.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Trey wrote:&lt;br&gt;That's sort of like saying that somebody is going to be irritated because they can't stoke up a hydroelectric plant with bellows...So what??&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I love your analogy.  :)   So what? So your business is losing money in the scenario he describes.&lt;br /&gt;&lt;br /&gt;I see this an indictment of relying too heavily on fancy developer tools to gloss over crappy code. If my code sucks in text form, but when I right-click on it a million lines of code in my IDE jumps to my rescue and explains it to me in pretty colors, then I'm helpless without that IDE. That sounds like a bad idea.&lt;br /&gt;&lt;br /&gt;In the stack of technology ignorance and dependency I've planted my flag here:&lt;br /&gt;&lt;br /&gt;- I don't really know or care about sub-atomic particles.&lt;br /&gt;- I don't really know or care how electrons flow through conductors.&lt;br /&gt;- I don't really know or care about chip design.&lt;br /&gt;- I don't really know or care how hard drives, memory, and monitors actually work.&lt;br /&gt;- I don't really know or care how the Linux kernel works.&lt;br /&gt;- I don't really know or care how perl is written (in C).&lt;br /&gt;- I don't really know or care how most of perl's core packages work (in Perl/XS/C).&lt;br /&gt;- I don't really know deeply or care how most of the CPAN modules I use work (in Perl/XS/C).&lt;br /&gt;- I know EXACTLY how the text of the Perl I wrote works. I do recursive grep's through text files to find out anything I need to know.&lt;br /&gt;- Syntax highlighting is a crutch for the weak.&lt;br /&gt;- Method auto-discovery is a crutch for the weak.&lt;br /&gt;- Per-keystroke debugging is a crutch for the weak.&lt;br /&gt;- Re-runnable images of crashes are a crutch for the weak.&lt;br /&gt;- All that other fancy crap in your IDE is fancy crap I don't need. For the weak.  :)&lt;br /&gt;&lt;br /&gt;Objectively, my gut-opinions about exactly where that line is are silly. Aren't they?&lt;br /&gt;&lt;br /&gt;If you take me and my Apple laptop running Terminal.app to ssh into a server and run vi, and next to me you sit a .NET guy running the latest Visual Studio on a mapped drive; is the total complexity of my dependency stack much smaller than his? (OS X is how many millions of lines of code?)&lt;br /&gt;&lt;br /&gt;I don't know. I've now spent an hour arguing with myself about it.  :)&lt;br /&gt;&lt;br /&gt;In any event, I don't thing it's the use or avoidance of an IDE that makes good or poor code. You can create beautiful or ugly code with the simplest or fanciest of tools. &lt;br /&gt;&lt;br /&gt;I do think he has a point. If your "...codebase is so complex that you need a large IDE to comprehend it." Then you're doing something wrong. Use an IDE because you want to, not because it's impossible to survive your mess without it.&lt;br /&gt;&lt;br /&gt;/me shakes his fist at XML Spy addicts&lt;br /&gt;&lt;br /&gt;Ponder,&lt;br /&gt;&lt;br /&gt;j&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="perl"/>
    <published>2010-02-06T17:19:00Z</published>
    <updated>2010-02-06T17:19:00Z</updated>
    <author>
      <name>Jay</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-958563956206735505.post-4376925160512635774</id>
  </entry>
  <entry>
    <title>An English-only Planet Iron Man</title>
    <link rel="alternate" href="http://www.dagolden.com/index.php/664/an-english-only-planet-iron-man/" type="text/html"/>
    <summary type="text">I’m very happy to know that Perl has global appeal from seeing all the
non-English Perl blogs aggregated on Planet Iron Man, but since I’m a
(typical American) monoglot, I’d prefer an Iron Man feed with only
English articles. So I made one.

It’s available at http://feeds.dagolden.com/ironman-english.xml. It
updates hourly from the master feed.

And for the curious, or for anyone who wants to adapt this for other
languages, here’s the Perl program that I whipped-up to create the feed:

# feedfilter.pl - downloads and filters the Perl Ironman feed for English
# entries. Results sent to STDOUT.
#
# The heuristic filters out entries unless the content is mostly latin
# characters and English is close to the best guess of a language.  Short
# entries with code seem to confuse Lingua::Identify, so we take entries that
# seem "close-enough".  Tuned via trial-and-error.
#
# Copyright (c) 2010 by David Golden - This may be used or copied under the
# same terms as Perl itself.

use 5.008001;
use strict;
use warnings;
use utf8;
use autodie;

use IO::File;
use Lingua::Identify qw(:language_identification);
use Time::Piece;
use URI;

use XML::Atom::Feed;
$XML::Atom::ForceUnicode = 1;
$XML::Atom::DefaultVersion = "1.0";

# Global heuristic tuning
my $latin_target = 0.95;  # 95% latin chars
my $lang_fuzz = 0.02;     # English within 2% probability of best language

run();

#--------------------------------------------------------------------------#

sub latin_ratio {
  my $string = shift;
  my $alpha =()= $string =~ /(\p{Alphabetic})/g;
  my $latin =()= $string =~ /(\p{Latin})/g;

  return 0 if ! $latin || !$alpha; # !$alpha probably redundant
  return $latin / $alpha;
}

sub run {
  my $in_feed = XML::Atom::Feed-&gt;new(URI-&gt;new("http://ironman.enlightenedperl.org"));

  my $out_feed = XML::Atom::Feed-&gt;new;
  $out_feed-&gt;title("Planet Iron Man: English Edition");
  $out_feed-&gt;subtitle( $in_feed-&gt;subtitle );
  $out_feed-&gt;id("tag:feeds.dagolden.com,".gmtime-&gt;year().":ironman:english");
  $out_feed-&gt;generator("XML::Atom/" . XML::Atom-&gt;VERSION);
  $out_feed-&gt;updated( gmtime-&gt;datetime . "Z" );
  for my $l ( $in_feed-&gt;link ) {
    $out_feed-&gt;link($l);
  }

  for my $e ( $in_feed-&gt;entries ) {
    my $content = $e-&gt;content-&gt;body;
    my $latin = latin_ratio($content);
    my %lang = langof($content);
    my $best = [sort { $lang{$b} &lt;=&gt; $lang{$a} } keys %lang]-&gt;[0];
    $lang{en} ||= 0;
    $out_feed-&gt;add_entry($e)
      if $latin &gt; $latin_target &amp;&amp; ($lang{$best} - $lang{en} &lt; $lang_fuzz);
  }

  binmode(STDOUT, ":utf8");
  print $out_feed-&gt;as_xml;
}</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>I’m very happy to know that Perl has global appeal from seeing all the non-English Perl blogs aggregated on <a href="http://ironman.enlightenedperl.org/">Planet Iron Man</a>, but since I’m a (typical American) monoglot, I’d prefer an Iron Man feed with only English articles.  So I made one.</p>
<p>It’s available at <a href="http://feeds.dagolden.com/ironman-english.xml">http://feeds.dagolden.com/ironman-english.xml</a>.  It updates hourly from the master feed.</p>
<p>And for the curious, or for anyone who wants to adapt this for other languages, here’s the Perl program that I whipped-up to create the feed:</p>
<pre class="brush: perl;">
# feedfilter.pl - downloads and filters the Perl Ironman feed for English
# entries. Results sent to STDOUT.
#
# The heuristic filters out entries unless the content is mostly latin
# characters and English is close to the best guess of a language.  Short
# entries with code seem to confuse Lingua::Identify, so we take entries that
# seem "close-enough".  Tuned via trial-and-error.
#
# Copyright (c) 2010 by David Golden - This may be used or copied under the
# same terms as Perl itself.

use 5.008001;
use strict;
use warnings;
use utf8;
use autodie;

use IO::File;
use Lingua::Identify qw(:language_identification);
use Time::Piece;
use URI;

use XML::Atom::Feed;
$XML::Atom::ForceUnicode = 1;
$XML::Atom::DefaultVersion = "1.0";

# Global heuristic tuning
my $latin_target = 0.95;  # 95% latin chars
my $lang_fuzz = 0.02;     # English within 2% probability of best language

run();

#--------------------------------------------------------------------------#

sub latin_ratio {
  my $string = shift;
  my $alpha =()= $string =~ /(\p{Alphabetic})/g;
  my $latin =()= $string =~ /(\p{Latin})/g;

  return 0 if ! $latin || !$alpha; # !$alpha probably redundant
  return $latin / $alpha;
}

sub run {
  my $in_feed = XML::Atom::Feed-&gt;new(URI-&gt;new("http://ironman.enlightenedperl.org"));

  my $out_feed = XML::Atom::Feed-&gt;new;
  $out_feed-&gt;title("Planet Iron Man: English Edition");
  $out_feed-&gt;subtitle( $in_feed-&gt;subtitle );
  $out_feed-&gt;id("tag:feeds.dagolden.com,".gmtime-&gt;year().":ironman:english");
  $out_feed-&gt;generator("XML::Atom/" . XML::Atom-&gt;VERSION);
  $out_feed-&gt;updated( gmtime-&gt;datetime . "Z" );
  for my $l ( $in_feed-&gt;link ) {
    $out_feed-&gt;link($l);
  }

  for my $e ( $in_feed-&gt;entries ) {
    my $content = $e-&gt;content-&gt;body;
    my $latin = latin_ratio($content);
    my %lang = langof($content);
    my $best = [sort { $lang{$b} &lt;=&gt; $lang{$a} } keys %lang]-&gt;[0];
    $lang{en} ||= 0;
    $out_feed-&gt;add_entry($e)
      if $latin &gt; $latin_target &amp;&amp; ($lang{$best} - $lang{en} &lt; $lang_fuzz);
  }

  binmode(STDOUT, ":utf8");
  print $out_feed-&gt;as_xml;
}
</pre>
</div>
    </content>
    <category term="perl-programming ironman"/>
    <published>2010-02-06T12:55:04Z</published>
    <updated>2010-02-06T12:55:04Z</updated>
    <author>
      <name>dagolden</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.dagolden.com/?p=664</id>
  </entry>
  <entry>
    <title>Padre, Firefox and Chrome</title>
    <link rel="alternate" href="http://ahmadzawawi.blogspot.com/2010/02/padre-and-firefox.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Lately there have been a discussion in #padre about integrating Padre
with "Edit with Emacs" Chrome extension. We found out that we need to
implement a server that services XmlHttp requests at port 9292 in Padre
to be able to integrate with that extension. It was a very interesting
discussion that led me to do more research on the topic. I learned that
there are Firefox add-ons that can edit text field or areas, launch your
favorite editor; i.e. Padre :) and then monitor files for changes and
reflect those changes in the browser. So here are some popular examples
of such add-ons for Firefox:

Firebug Add-onWebsite: http://www.getfirebug.com
Firebug adds a simple edit-the-contents-with-your-editor feature. It
turned out that you could easily configure Padre with Firebug. In fact
you can configure one or more editors:


It is All Text! Add-onWebsite:
https://addons.mozilla.org/en-US/firefox/addon/4125
This plugin unfortunately supports only one editor but it can actually
reflect saved changes from Padre by monitoring opened files.



Future plansIn the future I plan to create a Padre plugin that services
"Edit with Emacs" Chrome extension. Please let me know if there are any
browser add-ons/extensions of which I may have missed.</div>
    </summary>
    <content type="html">&lt;div&gt;Lately there have been a &lt;a href="http://irclog.perlgeek.de/padre/2010-02-03#i_1953952"&gt;discussion&lt;/a&gt; in &lt;a href="http://padre.perlide.org/irc.html?channel=padre"&gt;#padre&lt;/a&gt; about integrating &lt;a href="http://padre.perlide.org/"&gt;Padre&lt;/a&gt; with &lt;a href="https://chrome.google.com/extensions/detail/ljobjlafonikaiipfkggjbhkghgicgoh"&gt;"Edit with Emacs"&lt;/a&gt; Chrome extension. We found out that we need to implement a &lt;a href="http://github.com/stsquad/emacs_chrome/blob/master/servers/README"&gt;server&lt;/a&gt; that services XmlHttp requests at port 9292 in Padre to be able to integrate with that extension. It was a very interesting discussion that led me to do more research on the topic. I learned that there are Firefox add-ons that can edit text field or areas, launch your favorite editor; i.e. Padre :) and then monitor files for changes and reflect those changes in the browser. So here are some popular examples of such add-ons for Firefox:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://1.bp.blogspot.com/_pCUnIJflqm8/S20YkZ6wbOI/AAAAAAAAAkE/FuMQcXezNJU/s1600-h/firefox_addons.png"&gt;&lt;img src="http://1.bp.blogspot.com/_pCUnIJflqm8/S20YkZ6wbOI/AAAAAAAAAkE/FuMQcXezNJU/s320/firefox_addons.png" alt=""&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;Firebug Add-on&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Website: &lt;a href="http://www.getfirebug.com/"&gt;http://www.getfirebug.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Firebug adds a simple edit-the-contents-with-your-editor feature. It turned out that you could easily configure Padre with Firebug. In fact you can configure one or more editors:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_pCUnIJflqm8/S20RiSB4kMI/AAAAAAAAAj0/V9DbaQUUn0I/s1600-h/firefox_firebug.png"&gt;&lt;img src="http://1.bp.blogspot.com/_pCUnIJflqm8/S20RiSB4kMI/AAAAAAAAAj0/V9DbaQUUn0I/s320/firefox_firebug.png" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_pCUnIJflqm8/S20WiAzy1sI/AAAAAAAAAj8/swLySwaY7RY/s1600-h/firefox_configure_editors.png"&gt;&lt;img src="http://2.bp.blogspot.com/_pCUnIJflqm8/S20WiAzy1sI/AAAAAAAAAj8/swLySwaY7RY/s320/firefox_configure_editors.png" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;It is All Text! Add-on&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Website: &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/4125"&gt;https://addons.mozilla.org/en-US/firefox/addon/4125&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;This plugin unfortunately supports only one editor but it can actually reflect saved changes from Padre by monitoring opened files.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://2.bp.blogspot.com/_pCUnIJflqm8/S20Z8RStkCI/AAAAAAAAAkM/wuSVAZCrFxQ/s1600-h/firefox_itisalltext_preferences.png"&gt;&lt;img src="http://2.bp.blogspot.com/_pCUnIJflqm8/S20Z8RStkCI/AAAAAAAAAkM/wuSVAZCrFxQ/s320/firefox_itisalltext_preferences.png" alt=""&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_pCUnIJflqm8/S20aqElnusI/AAAAAAAAAkU/gT9HSfd8ETQ/s1600-h/firefox_itisalltext_pref_dlg.png"&gt;&lt;img src="http://3.bp.blogspot.com/_pCUnIJflqm8/S20aqElnusI/AAAAAAAAAkU/gT9HSfd8ETQ/s320/firefox_itisalltext_pref_dlg.png" alt=""&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;Future plans&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;In the future I plan to create a Padre plugin that services "Edit with Emacs" Chrome extension. Please let me know if there are any browser add-ons/extensions of which I may have missed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="padre perl"/>
    <published>2010-02-06T06:31:00Z</published>
    <updated>2010-02-06T06:31:00Z</updated>
    <author>
      <name>Ahmad M. Zawawi</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-7504008695982882539.post-4413661950788776400</id>
  </entry>
  <entry>
    <title>A Pic of Perl’s Benevolent Dictator For Life. A photo from YAPC::2009</title>
    <link rel="alternate" href="http://web-hero.net/adamantium/?p=106" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Larry Wall was such a nice and humble person. It was great to meet the
creator of Perl and it’s BDFL.
[IMAGE]</div>
    </summary>
    <content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Larry_Wall"&gt;Larry Wall&lt;/a&gt; was such a nice and humble person. It was great to meet the creator of Perl and it&amp;#8217;s &lt;a href="http://en.wikipedia.org/wiki/Benevolent_Dictator_For_Life"&gt;BDFL.&lt;/a&gt;&lt;br /&gt;
&lt;img src="http://web-hero.net/larry_and_shawn.jpg"&gt;&lt;/p&gt;
</content>
    <category term="Uncategorized"/>
    <published>2010-02-05T21:20:25Z</published>
    <updated>2010-02-05T21:20:25Z</updated>
    <author>
      <name>Shawn Faison (abesapien)</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://web-hero.net/adamantium/?p=106</id>
  </entry>
  <entry>
    <title>Motivating a contrarian contrary to their natural inclinations...</title>
    <link rel="alternate" href="http://ergoletterbag.blogspot.com/2010/02/motivating-contrarian-contrary-to-their.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I'm trying to figure out how to be more productive in areas which
interest me. Committing to writing and talking about Perl regularly seems
like a pretty reasonable way to grow skills in a manner which is likely
to be directed, thoughtful, and productive.

Planet Perl Iron Man is a great community effort to incentivize
thoughtful blogging and promote Perl. The catch is that I'm contrary by
nature. I want to be part of the group effort. But I also want to stand
apart from it. -It is hard to rationalize.

I also don't want to find myself writing something to maintain or
increase my status on some scoreboard. The contrarian answer that I've
come up with, is that I'm going to _try_ to stay closer to a "paper man"
than an "iron man". If I find myself posting too frequently, I'll scale
back. Perhaps that will have the positive affect of decreasing the
quantity but increasing the quality of my posts?

Another complication for me, is that for some inexplicable reason... I'm
less likely to follow through on personal interests if I make the mistake
of publicly mentioning them. Perhaps it is simply a fear of failure. It
doesn't matter if I try and fail when I don't care strongly about that
something in the first place. But to invest myself in something I _do_
care about... makes me feel particularly vulnerable. What if I fail? What
if I show my ignorance? How can I take criticism without taking it
personally?

I tell my kids all the time, that it is useless to compete with or try to
change others. The only person you can overcome... the only person you
can truly change is yourself. But I don't do a particularly good job of
leading by example. Time to change. Incremental change.

It is so much easier to stay on the sidelines and be a critic. It is
easier to judge others than allow yourself to be judged. It is easier to
sit back and think to myself "I could have done that"... than to actually
produce something of value. It is so much easier to talk than to do.

Enough talk. Do...</div>
    </summary>
    <content type="text">I'm trying to figure out how to be more productive in areas which interest me. Committing to writing and talking about Perl regularly seems like a pretty reasonable way to grow skills in a manner which is likely to be directed, thoughtful, and productive.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ironman.enlightenedperl.org/"&gt;Planet Perl Iron Man&lt;/a&gt; is a great community effort to incentivize thoughtful blogging and promote Perl. The catch is that I'm contrary by nature. I want to be part of the group effort. But I also want to stand apart from it. -It is hard to rationalize.&lt;br /&gt;&lt;br /&gt;I also don't want to find myself writing something to maintain or increase my status on some scoreboard. The contrarian answer that I've come up with, is that I'm going to _try_ to stay closer to a "paper man" than an "iron man". If I find myself posting too frequently, I'll scale back. Perhaps that will have the positive affect of decreasing the quantity but increasing the quality of my posts?&lt;br /&gt;&lt;br /&gt;Another complication for me, is that for some inexplicable reason... I'm less likely to follow through on personal interests if I make the mistake of publicly mentioning them. Perhaps it is simply a fear of failure. It doesn't matter if I try and fail when I don't care strongly about that something in the first place. But to invest myself in something I _do_ care about... makes me feel particularly vulnerable. What if I fail? What if I show my ignorance? How can I take criticism without taking it personally?&lt;br /&gt;&lt;br /&gt;I tell my kids all the time, that it is useless to compete with or try to change others. The only person you can overcome... the only person you can truly change is yourself. But I don't do a particularly good job of leading by example. Time to change. Incremental change.&lt;br /&gt;&lt;br /&gt;It is so much easier to stay on the sidelines and be a critic. It is easier to judge others than allow yourself to be judged. It is easier to sit back and think to myself "I could have done that"... than to actually produce something of value. It is so much easier to talk than to do.&lt;br /&gt;&lt;br /&gt;Enough talk. Do...&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="productivity motivation perl"/>
    <published>2010-02-05T20:30:00Z</published>
    <updated>2010-02-05T20:30:00Z</updated>
    <author>
      <name>Garrett</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-7321723569681012413.post-7906206652348141173</id>
  </entry>
  <entry>
    <title>Show Us The Whole Code</title>
    <link rel="alternate" href="http://www.shadowcat.co.uk/blog/matt-s-trout/show-us-the-whole-code/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Digg! submit to reddit Delicious RSS Feed Readers

When I'm being asked for help troubleshooting perl code - both out in the
community and for Shadowcat's professional services clients, one of the
things I'm always doing is asking for more information. In fact, the most
often heard cry on freenode's #perl channel is "show us the whole code".

Yet people always resist. "I already showed you the relevant parts", they
say. Unfortunately, they're ignoring something fairly essential - they're
showing us the parts they think are relevant. Which is fine, except that
knowing which parts are relevant is a key skill in debugging, and the
fact we've had much more practice at it is why we're being asked.

The thing is, the people concerned are usually trying to be helpful by
not burdening us with code that doesn't matter to the problem.
Unfortunately, that's just not how it works. So I say unto you:

If you're asking for help from me, please just show me all the code
involved in the first place

Seriously. I can skim through half a dozen files to find the bits that
matter way, way faster than I can go back and forth with you asking for
those bits one at a time. I've spent much of the past decade reading perl
code to work out what's going on, because I'm one of these strange people
who likes to read the source before committing to using a piece of
software.

But, ok, you're not convinced, so let me show you an example of something
that's quite close to a problem I had to solve for a client a couple of
years ago. Their Catalyst web application was refusing to start with
compilation errors and they were starting to get frantic.

Here's the code they showed me:

12 sub foo1 {
13   my $bar = shift;
14   warn "In foo1\n";
15   warn $bar;
16   warn "Leaving foo1\n";
17 }

And here's the error message it produced:

Global symbol "$bar" requires explicit package name at f-ed.up.pl line 15.

Now, I think the first response all of us would have there is erm, that
can't be right. Well, I can assure you that the client had misrepresented
neither the code nor the error message.

I looked at it, and, eliminating that which was impossible, came to the
only remaining conclusion, improbable though it was: The error was not in
that piece of code.

Unfortunately, our client didn't find this as satisfactory a conclusion
as I did, and we proceeded to have a debate about whether or not the
error was somewhere else and whether it was worthwhile them showing me
some more code (all this on an hours-based support contract) which I
ended by giving up and asking for a shell onto the dev box.

Once I got on there, I cracked open the relevant file and after staring
at it for a few minutes, spotted this:

12 sub foo1 {
13   my $bar = shift;
14   warn "In foo1\n";
15   warn $bar;
16   warn "Leaving foo1\n";
17 }
18 
19 sub foo2 {
20   my $fbar = shift;
21   warn "In foo2\n";
22   warn $bar;
23   warn "Leaving foo2\n";
24 }

Now, do we see the problem here?

Look again. It took me a while.

It's line 20 you need to be looking at.

And now you can explain why line 22 produces a strict error.

Wait? line 22?!

...

Precisely.

Now at this point, I made a lucky guess, went up to the top of the file,
added a single '#' character, and the error did indeed come from line 22
with that change.

The reason is: At some distant point in the past of this module, somebody
had decided they wanted a switch statement. So they'd loaded the
horrific, dangerous source filter known as Switch.pm. Then, after that,
they'd not needed the code that used it, so they'd =head1'ed it out as is
often done in perl to temporarily get rid of a block of code.

And then, over time, that commented code was committed, still commented,
and forgotten. The reuslting file looked roughly like this:

01 use strict;
02 use warnings;
03 
04 use Switch;
05 
06 =head1
07 switch ($foo) {
08   case 1 { print "yay\n" }
09 }
10 =cut
11 
12 sub foo1 {
13   my $bar = shift;
14   warn "In foo1\n";
15   warn $bar;
16   warn "Leaving foo1\n";
17 }
18 
19 sub foo2 {
20   my $fbar = shift;
21   warn "In foo2\n";
22   warn $bar;
23   warn "Leaving foo2\n";
24 }

The problem being that the #line directives Switch inserts are also
within the POD and therefore ignored. So line number reporting from then
on goes very, very wrong - see the original script and the same script
with line numbers if you want to play for yourself.

And, of course, since I'd already heard that albeit not seen it in
practice, if I'd seen the first half dozen lines of the file I'd've been
able to solve the problem and get our client back on track immediately,
instead of three quarters of an hour later.

So please, guys - for your own sanity as well as ours - when somebody
who's trying to help you asks for more information, provided you can give
them that information, please accept there's probably a reason for it.
And please, please.

Show Us The Whole Code.

Thank you.

-- mst, out</div>
    </summary>
    <content type="html">
&lt;p&gt;&lt;a href="http://digg.com/"&gt; &lt;img alt="Digg!" src="http://digg.com/img/badges/16x16-digg-guy.gif"&gt; &lt;/a&gt; &lt;a href="http://www.reddit.com/submit"&gt; &lt;img alt="submit to reddit" src="http://www.reddit.com/static/spreddit1.gif"&gt; &lt;/a&gt; &lt;a href="http://delicious.com/save"&gt; &lt;img alt="Delicious" src="http://static.delicious.com/img/delicious.small.gif"&gt; &lt;/a&gt; &lt;a&gt;&lt;img alt="" src="http://i.newsvine.com/_vine/images/identity/button_seednewsvine.gif"&gt;&lt;/a&gt; &lt;a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.yoursite.com%2Farticle.php%26title%3DThe%2BArticle%2BTitle"&gt; &lt;img alt="" src="http://cdn.stumble-upon.com/images/16x16_su_3d.gif"&gt;&lt;/a&gt; &lt;a title="Social Bookmark"&gt;&lt;img alt="RSS Feed Readers" src="http://www.seocentro.com/bookmark-rss/images/rss_button01.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div id="blog"&gt;&lt;p&gt;When I'm being asked for help troubleshooting perl code - both &lt;a href="http://www.irc.perl.org"&gt;out&lt;/a&gt; &lt;a href="http://lists.scys.co.uk"&gt;in&lt;/a&gt; &lt;a href="http://blogs.perl.org/"&gt;the&lt;/a&gt; &lt;a href="http://freenode.net"&gt;community&lt;/a&gt; and for &lt;a href="/services/"&gt;Shadowcat's professional services clients&lt;/a&gt;, one of the things I'm always doing is &lt;i&gt;asking for more information&lt;/i&gt;. In fact, the most often heard cry on &lt;a href="http://freenode.net/"&gt;freenode's&lt;/a&gt; #perl channel is &lt;b&gt;&amp;#34;show us the whole code&amp;#34;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Yet people always resist. &amp;#34;I already showed you the relevant parts&amp;#34;, they say. Unfortunately, they're ignoring something fairly essential - they're showing us &lt;i&gt;the parts they think are relevant&lt;/i&gt;. Which is fine, except that knowing which parts are relevant is a key skill in debugging, and the fact we've had much more practice at it is why we're being asked.&lt;/p&gt;&lt;p&gt;The thing is, the people concerned are usually &lt;b&gt;trying to be helpful&lt;/b&gt; by not burdening us with code that doesn't matter to the problem. Unfortunately, that's just not how it works. So I say unto you:&lt;/p&gt;&lt;p&gt;&lt;b&gt;If you're asking for help from me, please just show me all the code involved in the first place&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Seriously. I can skim through half a dozen files to find the bits that matter way, way faster than I can go back and forth with you asking for those bits one at a time. I've spent much of the past decade reading perl code to work out what's going on, because I'm one of these strange people who &lt;a href="../choosing-a-library"&gt;likes to read the source before committing to using a piece of software&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;But, ok, you're not convinced, so let me show you an example of something that's quite close to a problem I had to solve for a client a couple of years ago. Their &lt;a href="http://www.catalystframework.org"&gt;Catalyst web application&lt;/a&gt; was refusing to start with compilation errors and they were starting to get frantic.&lt;/p&gt;&lt;p&gt;Here's the code they showed me:&lt;/p&gt;&lt;pre&gt;&amp;#10;12 sub foo1 {&amp;#10;13   my &amp;#36;bar = shift;&amp;#10;14   warn &amp;#34;In foo1&amp;#92;n&amp;#34;;&amp;#10;15   warn &amp;#36;bar;&amp;#10;16   warn &amp;#34;Leaving foo1&amp;#92;n&amp;#34;;&amp;#10;17 }&amp;#10;&lt;/pre&gt;&lt;p&gt;And here's the error message it produced:&lt;/p&gt;&lt;pre&gt;&amp;#10;Global symbol &amp;#34;&amp;#36;bar&amp;#34; requires explicit package name at f-ed.up.pl line 15.&amp;#10;&lt;/pre&gt;&lt;p&gt;Now, I think the first response all of us would have there is &lt;i&gt;erm, that can't be right&lt;/i&gt;. Well, I can assure you that the client had misrepresented neither the code nor the error message.&lt;/p&gt;&lt;p&gt;I looked at it, and, eliminating that which was impossible, came to the only remaining conclusion, improbable though it was: The error was not in that piece of code.&lt;/p&gt;&lt;p&gt;Unfortunately, our client didn't find this as satisfactory a conclusion as I did, and we proceeded to have a debate about whether or not the error was somewhere else and whether it was worthwhile them showing me some more code (all this on &lt;a href="/services/support/"&gt;an hours-based support contract&lt;/a&gt;) which I ended by giving up and asking for a shell onto the dev box.&lt;/p&gt;&lt;p&gt;Once I got on there, I cracked open the relevant file and after staring at it for a few minutes, spotted this:&lt;/p&gt;&lt;pre&gt;&amp;#10;12 sub foo1 {&amp;#10;13   my &amp;#36;bar = shift;&amp;#10;14   warn &amp;#34;In foo1&amp;#92;n&amp;#34;;&amp;#10;15   warn &amp;#36;bar;&amp;#10;16   warn &amp;#34;Leaving foo1&amp;#92;n&amp;#34;;&amp;#10;17 }&amp;#10;18 &amp;#10;19 sub foo2 {&amp;#10;20   my &amp;#36;fbar = shift;&amp;#10;21   warn &amp;#34;In foo2&amp;#92;n&amp;#34;;&amp;#10;22   warn &amp;#36;bar;&amp;#10;23   warn &amp;#34;Leaving foo2&amp;#92;n&amp;#34;;&amp;#10;24 }&amp;#10;&lt;/pre&gt;&lt;p&gt;Now, do we see the problem here?&lt;/p&gt;&lt;p&gt;Look again. It took me a while.&lt;/p&gt;&lt;p&gt;It's line 20 you need to be looking at.&lt;/p&gt;&lt;p&gt;And now you can explain why line 22 produces a strict error.&lt;/p&gt;&lt;p&gt;Wait? line 22?!&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;&lt;i&gt;Precisely.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Now at this point, I made a lucky guess, went up to the top of the file, added a single '#' character, and the error did indeed come from line 22 with that change.&lt;/p&gt;&lt;p&gt;The reason is: At some distant point in the past of this module, somebody had decided they wanted a switch statement. So they'd loaded &lt;a href="http://search.cpan.org/perldoc?Switch"&gt;the horrific, dangerous source filter known as Switch.pm&lt;/a&gt;. Then, after that, they'd not needed the code that used it, so they'd =head1'ed it out as is often done in perl to temporarily get rid of a block of code.&lt;/p&gt;&lt;p&gt;And then, over time, that commented code was committed, still commented, and forgotten. The reuslting file looked roughly like this:&lt;/p&gt;&lt;pre&gt;&amp;#10;01 use strict;&amp;#10;02 use warnings;&amp;#10;03 &amp;#10;04 use Switch;&amp;#10;05 &amp;#10;06 =head1&amp;#10;07 switch (&amp;#36;foo) {&amp;#10;08   case 1 { print &amp;#34;yay&amp;#92;n&amp;#34; }&amp;#10;09 }&amp;#10;10 =cut&amp;#10;11 &amp;#10;12 sub foo1 {&amp;#10;13   my &amp;#36;bar = shift;&amp;#10;14   warn &amp;#34;In foo1&amp;#92;n&amp;#34;;&amp;#10;15   warn &amp;#36;bar;&amp;#10;16   warn &amp;#34;Leaving foo1&amp;#92;n&amp;#34;;&amp;#10;17 }&amp;#10;18 &amp;#10;19 sub foo2 {&amp;#10;20   my &amp;#36;fbar = shift;&amp;#10;21   warn &amp;#34;In foo2&amp;#92;n&amp;#34;;&amp;#10;22   warn &amp;#36;bar;&amp;#10;23   warn &amp;#34;Leaving foo2&amp;#92;n&amp;#34;;&amp;#10;24 }&amp;#10;&lt;/pre&gt;&lt;p&gt;The problem being that the #line directives Switch inserts are also within the POD and therefore ignored. So line number reporting from then on goes very, very wrong - see the &lt;a href="-files/f-ed.up.pl"&gt;original script&lt;/a&gt; and &lt;a href="-files/f-ed.up.txt"&gt;the same script with line numbers&lt;/a&gt; if you want to play for yourself.&lt;/p&gt;&lt;p&gt;And, of course, since I'd already heard that albeit not seen it in practice, if I'd seen the first half dozen lines of the file I'd've been able to solve the problem and get our client back on track immediately, instead of three quarters of an hour later.&lt;/p&gt;&lt;p&gt;So please, guys - for your own sanity as well as ours - when somebody who's trying to help you asks for more information, provided you &lt;i&gt;can&lt;/i&gt; give them that information, please accept there's probably a reason for it. And please, please.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Show Us The Whole Code.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Thank you.&lt;/p&gt;&lt;p&gt;-- mst, out&lt;/p&gt;&lt;/div&gt;

</content>
    <published>0</published>
    <updated>0</updated>
    <author>
      <name>nobody</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.shadowcat.co.uk/blog/matt-s-trout/show-us-the-whole-code/</id>
  </entry>
  <entry>
    <title>Why Perl?</title>
    <link rel="alternate" href="http://onperl.ru/onperl/2010/02/why-perl.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">На этой неделе в рассылке Moscow.pm я задал простой вопрос: как показать
начинающим программистам сильные стороны Perl?

В итоге получилось большое обсуждение на листе, где в том числе вспомнили
картинку про создание мира, кросспостинг (позже удаленный) на ru_perl с
руганью в комментариях в частности о том, надо ли лукавить перед
студентами, сгущая краски, пост на ru_perl о том, что студентам надо
преподавать не Perl, а Java и XML и перепост перепоста с интересным
обсуждением в комментариях о нишах языков.

Stay tuned, епта.</div>
    </summary>
    <content type="html">
        &lt;p&gt;На этой неделе&amp;nbsp;в рассылке Moscow.pm я задал простой вопрос: как показать начинающим программистам сильные стороны Perl?&lt;/p&gt;
&lt;p&gt;В итоге получилось &lt;a href="http://mail.pm.org/pipermail/moscow-pm/2010-February/007455.html"&gt;большое обсуждение на листе&lt;/a&gt;, где в том числе вспомнили &lt;a href="http://perlmonks.org.ru/vorota_v_perl/2010/02/why-perl.html"&gt;картинку про создание мира&lt;/a&gt;,&amp;nbsp;кросспостинг (позже удаленный) на ru_perl с руганью в комментариях в частности о том, надо ли лукавить перед студентами, сгущая краски, пост на ru_perl о том, что &lt;a href="http://community.livejournal.com/ru_perl/355641.html"&gt;студентам надо преподавать&lt;/a&gt; не Perl, а Java и XML&amp;nbsp;и &lt;a href="http://vrurg.livejournal.com/65183.html"&gt;перепост перепоста&lt;/a&gt; с интересным обсуждением в комментариях о нишах языков.&lt;/p&gt;
&lt;p&gt;Stay tuned, епта.&lt;/p&gt;
        
    </content>
    <category term="PM-группы Сообщество Язык discuss language moscow perl"/>
    <published>2010-02-05T19:50:43+01:00</published>
    <updated>2010-02-05T19:50:43+01:00</updated>
    <author>
      <name>ash</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:onperl.ru,2010:/onperl//1.131</id>
  </entry>
  <entry>
    <title>NYTProf-3 is Out!</title>
    <link rel="alternate" href="http://community.livejournal.com/shlomif_tech/44836.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Tim Bunce writes on his blog about the new features in Devel-NYTProf
version 3. Devel-NYTProf is a profiler for the Perl programming language,
which has put all the previous attempts in profiling in the dust, and now
it's even better than before. Enjoy! (Thanks to Fred Moyer's post on the
San-Fransisco Perl Mongers mailing list).</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
<a href="http://blog.timbunce.org/2009/12/24/nytprof-v3-worth-the-wait/">Tim
Bunce writes on his blog about the new features in 
Devel-NYTProf version 3</a>. Devel-NYTProf is a profiler for the 
<a href="http://perl-begin.org/">Perl programming language</a>, which has
put all the previous attempts in profiling in the dust, and now it's even 
better than before. Enjoy! (Thanks to 
<a href="http://mail.pm.org/pipermail/sanfrancisco-pm/2010-February/002704.html">Fred 
Moyer's post</a> on the San-Fransisco Perl Mongers mailing list).
</p>
      </div>
    </content>
    <category term="3 version perl profiler release nytprof"/>
    <published>2010-02-05T16:31:51Z</published>
    <updated>2010-02-05T16:31:51Z</updated>
    <author>
      <name>Shlomi Fish ( shlomif@iglu.org.il )</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://community.livejournal.com/shlomif_tech/44836.html</id>
  </entry>
  <entry>
    <title>Frozen Perl starts today</title>
    <link rel="alternate" href="http://blog.lib.umn.edu/leonard/perl/2010/02/frozen-perl-starts-today.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"> I hope you are coming to Minneapolis tomorrow to Frozen Perl!
The Classes are today, If you are in one of the classes why are you
reading this? You should be paying attention to brian or Dave.
Come join us virtually if you cannot join us IRL
The weather this year is a little colder than the last two years, so this
might be the first workshop that is actually below the freezing point. We
are also looking at a fresh coating of snow right now, but nothing as
horrible as the east coast.
I look forward to seeing everyone tomorrow.</div>
    </summary>
    <content type="text">
        I hope you are coming to Minneapolis tomorrow to Frozen Perl!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Classes are today, If you are in one of the classes why are you reading this? You should be paying attention to brian or Dave.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Come join us &lt;a href="irc://irc.perl.org/#fp"&gt;virtually&lt;/a&gt; if you cannot join us IRL&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The weather this year is a little colder than the last two years, so this might be the first workshop that is actually below the freezing point. We are also looking at a fresh coating of snow right now, but nothing as horrible as the east coast.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I look forward to seeing everyone tomorrow.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
        
    </content>
    <category term="ACT frozen perl 10 irc ironman"/>
    <published>2010-02-05T14:02:55Z</published>
    <updated>2010-02-05T14:02:55Z</updated>
    <author>
      <name>leonard</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blog.lib.umn.edu,2010:/leonard/perl//10510.216399</id>
  </entry>
  <entry>
    <title>Using JQuery and AJAX in Mojolicious</title>
    <link rel="alternate" href="http://vti.showmetheco.de/articles/2010/02/using-jquery-and-ajax-in-mojolicious.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I don't really know how to program in JavaScript and that's why I chose
JQuery to do all the job with AJAX. Let's see how short and easy the
solution in Mojolicious::Lite could be.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        
<p>I don't really know how to program in JavaScript and that's why I chose JQuery to do all the job with AJAX.
Let's see how short and easy the solution in <a href="http://search.cpan.org/perldoc?Mojolicious%3A%3ALite" class="podlinkpod">Mojolicious::Lite</a> could be.</p>

      </div>
    </content>
    <category term="Perl Mojolicious JavaScript JSON AJAX JQuery"/>
    <published>2010-02-05T10:07:00+01:00</published>
    <updated>2010-02-05T10:07:00+01:00</updated>
    <author>
      <name>nobody</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://vti.showmetheco.de/articles/2010/02/using-jquery-and-ajax-in-mojolicious.html</id>
  </entry>
  <entry>
    <title>Why Perl?</title>
    <link rel="alternate" href="http://perlmonks.org.ru/vorota_v_perl/2010/02/why-perl.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Лучший ответ в moscow.pm:

Я считаю, что те кто переходит с перла на пайтон/руби - еретики и скорее
всего попадут в ад.

Why Perl?</div>
    </summary>
    <content type="html">
        &lt;p&gt;Лучший ответ в moscow.pm:&lt;/p&gt;
&lt;p&gt;Я считаю, что те кто переходит с перла на пайтон/руби - еретики и скорее всего попадут в ад.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://perlmonks.org.ru/vorota_v_perl/assets_c/2010/02/lisp-150.html"&gt;&lt;img alt="Why Perl?" src="http://perlmonks.org.ru/vorota_v_perl/assets_c/2010/02/lisp-thumb-400x118-150.jpg"&gt;&lt;/a&gt;&lt;a href="http://xkcd.com/224/"&gt;&lt;/a&gt;&lt;/p&gt;
        
    </content>
    <category term="Заметки программиста holywar perl"/>
    <published>2010-02-05T07:42:54Z</published>
    <updated>2010-02-05T07:42:54Z</updated>
    <author>
      <name>Monks</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:perlmonks.org.ru,2010:/vorota_v_perl//1.47</id>
  </entry>
  <entry>
    <title>[Perl]Perlの最適化の概要</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/gfx/20100205/1265344597" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Perlコアの最適化をまとめておく。

まず，opcodeの最適化を主に行っているのは，op.cのPerl_peep()である。ただし，これは最適化以外の処理，たとえばuse
strict 'subs'の下でベアワードに対して致命的エラーを投げる，なども行っている。

さて，Perl_peep()の最適化はだいたい以下の3パターンである。

  *  不要なopcodeを削除

      *  opcodeを構築する際につかわれる，op_stubやop_nullなどのスタブノード

      *  op_scalar*1など，実質的な意味を持たないopcode

  *  よくあるopcodeパターンを一つにまとめる

      *  "reverse sort LIST"において，op_sortの逆順ソートビットを立ててop_reverseを消す*2

      *  $arrary[10]などの定数添え字が小さな定数の場合，op_aelemfastに変換してopcodeに添え字を埋め込む

  *  データに細工を施す

      *  $hash{foo}などの定数キーをShared SVに変換する

このうち，頻出するopcodeパターンを一つにまとめる方法は実装も試験も容易であり，いろいろ試してもいいかもしれない。その場合，「頻出するopcodeパターン」を探すようなプロファイラをまず書く必要があるだろう。

また，現状の最適化器は本格的なコンパイラが行うようなアグレッシブなコード書き換えは行っていないので，それを考慮すると試せることはまだ沢山あるように思う。

*1：CORE::scalar()の実体

*2：sortの最適化についてはOptimization of sort()で解説済み</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>Perlコアの最適化をまとめておく。</p>
			<p>まず，opcodeの最適化を主に行っているのは，<a href="http://cpansearch.perl.org/src/DAPM/perl-5.10.1/op.c">op.c</a>のPerl_peep()である。ただし，これは最適化以外の処理，たとえば<code>use strict 'subs'</code>の下でベアワードに対して致命的エラーを投げる，なども行っている。</p>
			<p>さて，Perl_peep()の最適化はだいたい以下の3パターンである。</p>
			<ul>
				<li> 不要なopcodeを削除
				<ul>
					<li> opcodeを構築する際につかわれる，op_stubやop_nullなどのスタブノード</li>
					<li> op_scalar<span class="footnote"><a href="/gfx/#f1" name="fn1" title="CORE::scalar()の実体">*1</a></span>など，実質的な意味を持たないopcode</li>
				</ul>
				</li>
				<li> よくあるopcodeパターンを一つにまとめる
				<ul>
					<li> "reverse sort LIST"において，op_sortの逆順ソートビットを立ててop_reverseを消す<span class="footnote"><a href="/gfx/#f2" name="fn2" title="sortの最適化については[http://d.hatena.ne.jp/gfx/20090531/1243743871:title=Optimization of sort()]で解説済み">*2</a></span></li>
					<li> $arrary[10]などの定数添え字が小さな定数の場合，op_aelemfastに変換してopcodeに添え字を埋め込む</li>
				</ul>
				</li>
				<li> データに細工を施す
				<ul>
					<li> $hash{foo}などの定数キーをShared SVに変換する</li>
				</ul>
				</li>
			</ul>
			<p>このうち，頻出するopcodeパターンを一つにまとめる方法は実装も試験も容易であり，いろいろ試してもいいかもしれない。その場合，「頻出するopcodeパターン」を探すようなプロファイラをまず書く必要があるだろう。</p>
			<p>また，現状の最適化器は本格的なコンパイラが行うようなアグレッシブなコード書き換えは行っていないので，それを考慮すると試せることはまだ沢山あるように思う。</p>
		</div>
		<div class="footnote">
			<p class="footnote"><a href="/gfx/#fn1" name="f1">*1</a>：CORE::scalar()の実体</p>
			<p class="footnote"><a href="/gfx/#fn2" name="f2">*2</a>：sortの最適化については<a href="http://d.hatena.ne.jp/gfx/20090531/1243743871">Optimization of sort()</a>で解説済み</p>
		</div>
</div>
    </content>
    <category term="Perl"/>
    <published>2010-02-05T13:36:37+09:00</published>
    <updated>2010-02-05T13:36:37+09:00</updated>
    <author>
      <name>gfx</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/gfx/20100205/1265344597</id>
  </entry>
  <entry>
    <title>[Faster]Faster.pm の現状と課題</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100205/1265343291" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">ちょっとみてみたかんじで、いくつか感じたことをメモしておく。

JIT 素人すぎるので、まとはずれなこといってるとおもいますけど。

不安定

perl -Mblib -MFaster -e 'use Plack::Loader; Plack::Loader-&gt;load("Standalone")-&gt;run(sub {[200,[],"OK"]})'

が SEGV するとか。

速度が 20% しかはやくならない

たしかに価値はあるが、もうちょいアップするとうれしい。

すべての関数をJITしてる

現実的には特定のホットスポットのみをやった方がいいのではないか。ちょっとおおきいものをコンパイルすると起動に鬼のように時間がかかる。

たとえば sub foo :Optimize { } のようにアトリビュートつけたものだけをやるとか。

gcc を起動してる

op tree を c に変換して gcc してるので、コンパイルに時間がかかる。移植性はあるだろうけど、遅い。

直接マシン語にかえられれば起動速度がましになるのではないか。

opcode のインライン展開

現在、Perl_pp_add() などはいちいち手でよんでるが、これをインライン展開すればはやいのではないか。</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>ちょっとみてみたかんじで、いくつか感じたことをメモしておく。</p>
			<p>JIT 素人すぎるので、まとはずれなこといってるとおもいますけど。</p>
			<h4>不安定</h4>
<pre>
perl -Mblib -MFaster -e 'use Plack::Loader; Plack::Loader-&gt;load("Standalone")-&gt;run(sub {[200,[],"OK"]})'
</pre>

			<p>が SEGV するとか。</p>
			<h4>速度が 20% しかはやくならない</h4>
			<p>たしかに価値はあるが、もうちょいアップするとうれしい。</p>
			<h4>すべての関数をJITしてる</h4>
			<p>現実的には特定のホットスポットのみをやった方がいいのではないか。ちょっとおおきいものをコンパイルすると起動に鬼のように時間がかかる。</p>
			<p>たとえば sub foo :Optimize { } のようにアトリビュートつけたものだけをやるとか。</p>
			<h4>gcc を起動してる</h4>
			<p>op tree を c に変換して gcc してるので、コンパイルに時間がかかる。移植性はあるだろうけど、遅い。</p>
			<p>直接マシン語にかえられれば起動速度がましになるのではないか。</p>
			<h4>opcode のインライン展開</h4>
			<p>現在、Perl_pp_add() などはいちいち手でよんでるが、これをインライン展開すればはやいのではないか。</p>
		</div>
</div>
    </content>
    <category term="Faster"/>
    <published>2010-02-05T13:14:51+09:00</published>
    <updated>2010-02-05T13:14:51+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100205/1265343291</id>
  </entry>
  <entry>
    <title>[Faster][Perl]Faster.pm の最適化</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100205/1265333429" type="text/html"/>
    <summary type="text">Faster.pm がやってることは、基本的には Perl VM がやってる処理を C のコードにかきくだしただけなのです。生成されてる C
のコードは以下のようなかんじだ。

ここからさらに最適化できれば、ぐっと速くできるのだけど。

#define PERL_NO_GET_CONTEXT#define PERL_CORE#include &lt;assert.h&gt;#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#if 1# define faster_PUSHMARK_PREALLOC(count) while (PL_markstack_ptr + (count) &gt;= PL_markstack_max) markstack_grow ()# define faster_PUSHMARK(p) *++PL_markstack_ptr = (p) - PL_stack_base#else# define faster_PUSHMARK_PREALLOC(count) 1# define faster_PUSHMARK(p) PUSHMARK(p)#endif#define RUNOPS_TILL(op)                                         \  while (nextop != (op))                                        \    {                                                           \      PERL_ASYNC_CHECK ();                                      \      PL_op = nextop; nextop = (PL_op-&gt;op_ppaddr)(aTHX);        \    }
OP *F485e855f8965caa3b40498ee2da71dcc (pTHX)
{
  register OP *nextop = (OP *)34431168L;
  faster_PUSHMARK_PREALLOC (1);op_34431168: /* nextstate */  PL_curcop = (COP *)nextop;
  PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
  FREETMPS;
  nextop = (OP *)34430960L;
  goto op_34430960;op_34430960: /* pushmark */  faster_PUSHMARK (PL_stack_sp);
  nextop = (OP *)34431264L;
  goto op_34431264;op_34431264: /* aelemfast */  { dSP; EXTEND (SP, 3); PUTBACK; }
  {
    AV *av = GvAV ((GV *)34279824L);
    SV **svp = av_fetch (av, 0, 0); SV *sv = svp ? *svp : 
    if (SvGMAGICAL (sv)) sv = sv_mortalcopy (sv);
    dSP;
    PUSHs (sv);
    PUTBACK;
  }
  nextop = (OP *)34431424L;
  goto op_34431424;op_34431424: /* const */  { dSP; PUSHs ((SV *)34392504L); PUTBACK; }
  nextop = (OP *)34430720L;
  goto op_34430720;op_34430720: /* add */  PL_op = nextop; nextop = Perl_pp_add (aTHX);
  goto op_34431760;op_34431760: /* const */  { dSP; PUSHs ((SV *)34280232L); PUTBACK; }
  nextop = (OP *)34431040L;
  goto op_34431040;op_34431040: /* print */  PERL_ASYNC_CHECK ();
  PL_op = nextop; nextop = Perl_pp_print (aTHX);
  goto op_34432192;op_34432192: /* leavesub */  PERL_ASYNC_CHECK ();
  return nextop;op_0:
  return 0;
}</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>Faster.pm がやってることは、基本的には Perl VM がやってる処理を C のコードにかきくだしただけなのです。生成されてる C のコードは以下のようなかんじだ。</p>
			<p>ここからさらに最適化できれば、ぐっと速くできるのだけど。</p>
<pre class="syntax-highlight">
<span class="synPreProc">#define PERL_NO_GET_CONTEXT</span>
<span class="synPreProc">#define PERL_CORE</span>

<span class="synPreProc">#include </span><span class="synConstant">&lt;assert.h&gt;</span>

<span class="synPreProc">#include </span><span class="synConstant">"EXTERN.h"</span>
<span class="synPreProc">#include </span><span class="synConstant">"perl.h"</span>
<span class="synPreProc">#include </span><span class="synConstant">"XSUB.h"</span>

<span class="synPreProc">#if </span><span class="synConstant">1</span>
<span class="synPreProc"># define faster_PUSHMARK_PREALLOC(count) </span><span class="synStatement">while</span><span class="synPreProc"> (PL_markstack_ptr + (count) &gt;= PL_</span>
markstack_max<span class="synError">)</span> markstack_grow ()
<span class="synPreProc"># define faster_PUSHMARK(p) *++PL_markstack_ptr = (p) - PL_stack_base</span>
<span class="synPreProc">#else</span>
<span class="synPreProc"># define faster_PUSHMARK_PREALLOC(count) </span><span class="synConstant">1</span>
<span class="synPreProc"># define faster_PUSHMARK(p) PUSHMARK(p)</span>
<span class="synPreProc">#endif</span>

<span class="synPreProc">#define RUNOPS_TILL(op)                                         \</span>
<span class="synPreProc">  </span><span class="synStatement">while</span><span class="synPreProc"> (nextop != (op))                                        \</span>
<span class="synPreProc">    {                                                           \</span>
<span class="synPreProc">      PERL_ASYNC_CHECK ();                                      \</span>
<span class="synPreProc">      PL_op = nextop; nextop = (PL_op-&gt;op_ppaddr)(aTHX);        \</span>
<span class="synPreProc">    }</span>

OP *F485e855f8965caa3b40498ee2da71dcc (pTHX)
{
  <span class="synType">register</span> OP *nextop = (OP *)<span class="synConstant">34431168L</span>;
  faster_PUSHMARK_PREALLOC (<span class="synConstant">1</span>);
<span class="synStatement">op_34431168</span>: <span class="synComment">/* nextstate */</span>
  PL_curcop = (COP *)nextop;
  PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
  FREETMPS;
  nextop = (OP *)<span class="synConstant">34430960L</span>;
  <span class="synStatement">goto</span> op_34430960;
<span class="synStatement">op_34430960</span>: <span class="synComment">/* pushmark */</span>
  faster_PUSHMARK (PL_stack_sp);
  nextop = (OP *)<span class="synConstant">34431264L</span>;
  <span class="synStatement">goto</span> op_34431264;
<span class="synStatement">op_34431264</span>: <span class="synComment">/* aelemfast */</span>
  { dSP; EXTEND (SP, <span class="synConstant">3</span>); PUTBACK; }
  {
    AV *av = GvAV ((GV *)<span class="synConstant">34279824L</span>);
    SV **svp = av_fetch (av, <span class="synConstant">0</span>, <span class="synConstant">0</span>); SV *sv = svp ? *svp : 
    <span class="synStatement">if</span> (SvGMAGICAL (sv)) sv = sv_mortalcopy (sv);
    dSP;
    PUSHs (sv);
    PUTBACK;
  }
  nextop = (OP *)<span class="synConstant">34431424L</span>;
  <span class="synStatement">goto</span> op_34431424;
<span class="synStatement">op_34431424</span>: <span class="synComment">/* const */</span>
  { dSP; PUSHs ((SV *)<span class="synConstant">34392504L</span>); PUTBACK; }
  nextop = (OP *)<span class="synConstant">34430720L</span>;
  <span class="synStatement">goto</span> op_34430720;
<span class="synStatement">op_34430720</span>: <span class="synComment">/* add */</span>
  PL_op = nextop; nextop = Perl_pp_add (aTHX);
  <span class="synStatement">goto</span> op_34431760;
<span class="synStatement">op_34431760</span>: <span class="synComment">/* const */</span>
  { dSP; PUSHs ((SV *)<span class="synConstant">34280232L</span>); PUTBACK; }
  nextop = (OP *)<span class="synConstant">34431040L</span>;
  <span class="synStatement">goto</span> op_34431040;
<span class="synStatement">op_34431040</span>: <span class="synComment">/* print */</span>
  PERL_ASYNC_CHECK ();
  PL_op = nextop; nextop = Perl_pp_print (aTHX);
  <span class="synStatement">goto</span> op_34432192;
<span class="synStatement">op_34432192</span>: <span class="synComment">/* leavesub */</span>
  PERL_ASYNC_CHECK ();
  <span class="synStatement">return</span> nextop;
<span class="synStatement">op_0</span>:
  <span class="synStatement">return</span> <span class="synConstant">0</span>;
}
</pre>

		</div>
</div>
    </content>
    <category term="Faster Perl"/>
    <published>2010-02-05T10:30:29+09:00</published>
    <updated>2010-02-05T10:30:29+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100205/1265333429</id>
  </entry>
  <entry>
    <title>Faster.pm が 5.10.1 と 5.8.9 でうごくようにしてみた。</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100205/1265328957" type="text/html"/>
    <summary type="text">5.10.0 でしかうごかないことで有名な Faster.pm ですが、コードをよんでみたところ、ロジックがちがうくさいので、なおしたら
5.10.1 ではうごいた(in_perl の部分)。

あと、global destruction 時にも JIT がうごいてて、これが原因でおちてるくさかったので PL_dirty
みるようにした。この変更により、Perl 5.8.9 でもうごくようになった。Global Destruction
時は不安定な動作になるし、そもそも終了処理をかけてる最中に jIT しても意味ないので、これは必要な処理といえる。

2点の変更とも、たまたま perl5.10.0 ではうごいてただけな気がする。

diff --git a/Faster.xs b/Faster.xsindex e568ab2..3c6e174 100644--- a/Faster.xs+++ b/Faster.xs@@ -15,7 +15,7 @@ faster_entersub (pTHX) {
   static int in_perl;
-  if (!PL_compcv || in_perl) // only when not compiling, reduces recompiling due to op-address-shift+  if (!PL_compcv &amp;&amp; in_perl==0 &amp;&amp; !PL_dirty) // only when not compiling, reduces recompiling due to op-address-shift, global destruction
     {
       dSP;
       dTOPss;</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>5.10.0 でしかうごかないことで有名な Faster.pm ですが、コードをよんでみたところ、ロジックがちがうくさいので、なおしたら 5.10.1 ではうごいた(in_perl の部分)。</p>
			<p>あと、global destruction 時にも JIT がうごいてて、これが原因でおちてるくさかったので PL_dirty みるようにした。この変更により、Perl 5.8.9 でもうごくようになった。Global Destruction 時は不安定な動作になるし、そもそも終了処理をかけてる最中に jIT しても意味ないので、これは必要な処理といえる。</p>
			<p>2点の変更とも、たまたま perl5.10.0 ではうごいてただけな気がする。</p>
<pre class="syntax-highlight">
<span class="synType">diff --git a/Faster.xs b/Faster.xs</span>
index e568ab2..3c6e174 100644
<span class="synType">--- a/Faster.xs</span>
<span class="synType">+++ b/Faster.xs</span>
<span class="synStatement">@@ -15,7 +15,7 @@</span><span class="synPreProc"> faster_entersub (pTHX)</span>
 {
   static int in_perl;

<span class="synSpecial">-  if (!PL_compcv || in_perl) // only when not compiling, reduces recompiling due to op-address-shift</span>
<span class="synIdentifier">+  if (!PL_compcv &amp;&amp; in_perl==0 &amp;&amp; !PL_dirty) // only when not compiling, reduces</span>
 recompiling due to op-address-shift, global destruction
     {
       dSP;
       dTOPss;
</pre>

		</div>
</div>
    </content>
    <published>2010-02-05T09:15:57+09:00</published>
    <updated>2010-02-05T09:15:57+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100205/1265328957</id>
  </entry>
  <entry>
    <title>LL脳な人でもこれぐらいは覚えておくとうれしいgdbのつかいかた。または猫でもわかるgdb講座</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100205/1265328621" type="text/html"/>
    <summary type="text">LLつかってても「ばすえらーになるー」っていう状況ってたまにあるわけですが、LL
しか普段つかわないゆとりは、ここでお手あげになってしまったりすることがままあります。

で、「ばすえらーになるんですが」ってときの最低限これだけはやってみたらどうか、という話。「えー、わたし gdb
とかわかんないしー」とかいってる人でもこれぐらいならできるんじゃないかなーっと。

------------------------------------------------------------------------

perl t/00_load.t

というコマンドで segv するという場合、gdb をつかって

% gdb --args perl t/00_load.t

とうつ。

すると、以下のようにプロンプトがでるので、"run" とうつ。これでスクリプトがはしりはじめる。

% gdb --args perl t/00_load.t
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
&lt;http://www.gnu.org/software/gdb/bugs/&gt;...
Reading symbols from /home/tokuhirom/local/multiperl/5.8.9-DEBUGGING-usethreads/bin/perl...done.
(gdb)

そうすると、そのうちおちるでしょうと。

(gdb) run
Starting program: perl t/00_load.t
[Thread debugging using libthread_db enabled]
1..1
ok 1

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff613a4d6 in do_retrieve (my_perl=0x74d010, f=0x771290, in=0x0,
    optype=0) at Storable.xs:6023
warning: Source file is more recent than executable.
6023

そしたら bt ってうつと、バックトレースがとれますよ、と。で、これをみると原因は Storable くさいということがわかりますよ、と。

(gdb) bt
#0  0x00007ffff613a4d6 in do_retrieve (my_perl=0x74d010, f=0x771290, in=0x0,
    optype=0) at Storable.xs:6023
#1  0x00007ffff613ab74 in pretrieve (my_perl=0x74d010, cv=&lt;value optimized out&gt;)
    at Storable.xs:6253
#2  XS_Storable_pretrieve (my_perl=0x74d010, cv=&lt;value optimized out&gt;)
    at Storable.xs:6452
#3  0x0000000000457e93 in Perl_pp_entersub (my_perl=0x74d010) at pp_hot.c:2862
#4  0x0000000000436ede in Perl_runops_debug (my_perl=0x74d010) at dump.c:1639
#5  0x00000000004539f6 in Perl_call_sv (my_perl=&lt;value optimized out&gt;,
    sv=0xa62ef0, flags=134) at perl.c:2731
#6  0x00007ffff5f274bb in faster_entersub (my_perl=&lt;value optimized out&gt;)
    at Faster.xs:47
#7  0x000000000044e1e6 in S_call_body (my_perl=0x74d010, myop=0xa161c0,
    is_eval=14 '\016') at perl.c:2801
#8  0x00000000004539f6 in Perl_call_sv (my_perl=&lt;value optimized out&gt;,
    sv=0x851230, flags=150) at perl.c:2731
#9  0x0000000000463ef2 in Perl_sv_clear (my_perl=0x74d010, sv=0x85f260)
    at sv.c:4642
#10 0x00000000004646f5 in Perl_sv_free (my_perl=0x74d010, sv=0x85f260)
    at sv.c:4862
#11 0x0000000000460142 in S_visit (my_perl=0x74d010,
    f=0x476740 &lt;do_clean_objs&gt;, flags=524288, mask=524288) at sv.c:370
#12 0x000000000046019f in Perl_sv_clean_objs (my_perl=0x7ffff613ac4e)
    at sv.c:471
#13 0x0000000000455f48 in perl_destruct (my_perl=&lt;value optimized out&gt;)
    at perl.c:881
#14 0x0000000000421cb0 in main (argc=3, argv=0x7fffffffe2b8, env=0x7fffffffe2d8)
    at perlmain.c:111

まあ、このぐらいの操作おぼえとくだけでも、XS が犯人か Perl そのものが犯人かは判定が容易にできる。XS
が犯人だってわかれば、その周辺があやしいってのがすぐわかるんで、再現するコードをつくって、作者に報告すればいい(パッチをつくれるとなおいい)。

なお、perl 本体のぶぶんの行数とか表示させるには -DDEBUGGING つきで perl をコンパイルしておくことが必要。

なお、これ以上くわしいつかいかたは、http://d.hatena.ne.jp/stanaka/20080630/1214780557
のへんを参考にするといいですね。

------------------------------------------------------------------------

なお Perl5 が SEGV する場合、1割は mod_perl に起因、9割5分は XS
に起因、のこりの5分がperl本体に起因しています。ただし、のこりの5分のうち90%ぐらいはwell knownな問題です。http://perl-users.jp/articles/crashing_perl.html
このへんには目をとおしておくとよいです。</summary>
    <content type="html">
		&lt;div class="section"&gt;
			&lt;p&gt;LLつかってても「ばすえらーになるー」っていう状況ってたまにあるわけですが、LL しか普段つかわないゆとりは、ここでお手あげになってしまったりすることがままあります。&lt;/p&gt;
			&lt;p&gt;で、「ばすえらーになるんですが」ってときの最低限これだけはやってみたらどうか、という話。「えー、わたし gdb とかわかんないしー」とかいってる人でもこれぐらいならできるんじゃないかなーっと。&lt;/p&gt;
			&lt;p&gt;&lt;hr&gt;&lt;/p&gt;
&lt;pre&gt;
perl t/00_load.t
&lt;/pre&gt;

			&lt;p&gt;というコマンドで segv するという場合、gdb をつかって&lt;/p&gt;
&lt;pre&gt;
% gdb --args perl t/00_load.t
&lt;/pre&gt;

			&lt;p&gt;とうつ。&lt;/p&gt;
			&lt;p&gt;すると、以下のようにプロンプトがでるので、"run" とうつ。これでスクリプトがはしりはじめる。&lt;/p&gt;
&lt;pre&gt;
% gdb --args perl t/00_load.t
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;#60;http://gnu.org/licenses/gpl.html&amp;#62;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type &amp;#34;show copying&amp;#34;
and &amp;#34;show warranty&amp;#34; for details.
This GDB was configured as &amp;#34;x86_64-linux-gnu&amp;#34;.
For bug reporting instructions, please see:
&amp;#60;http://www.gnu.org/software/gdb/bugs/&amp;#62;...
Reading symbols from /home/tokuhirom/local/multiperl/5.8.9-DEBUGGING-usethreads/bin/perl...done.
(gdb)
&lt;/pre&gt;

			&lt;p&gt;そうすると、そのうちおちるでしょうと。&lt;/p&gt;
&lt;pre&gt;
(gdb) run
Starting program: perl t/00_load.t
&amp;#91;Thread debugging using libthread_db enabled]
1..1
ok 1

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff613a4d6 in do_retrieve (my_perl=0x74d010, f=0x771290, in=0x0,
    optype=0) at Storable.xs:6023
warning: Source file is more recent than executable.
6023
&lt;/pre&gt;

			&lt;p&gt;そしたら bt ってうつと、バックトレースがとれますよ、と。で、これをみると原因は Storable くさいということがわかりますよ、と。&lt;/p&gt;
&lt;pre&gt;
(gdb) bt
#0  0x00007ffff613a4d6 in do_retrieve (my_perl=0x74d010, f=0x771290, in=0x0,
    optype=0) at Storable.xs:6023
#1  0x00007ffff613ab74 in pretrieve (my_perl=0x74d010, cv=&amp;#60;value optimized out&amp;#62;)
    at Storable.xs:6253
#2  XS_Storable_pretrieve (my_perl=0x74d010, cv=&amp;#60;value optimized out&amp;#62;)
    at Storable.xs:6452
#3  0x0000000000457e93 in Perl_pp_entersub (my_perl=0x74d010) at pp_hot.c:2862
#4  0x0000000000436ede in Perl_runops_debug (my_perl=0x74d010) at dump.c:1639
#5  0x00000000004539f6 in Perl_call_sv (my_perl=&amp;#60;value optimized out&amp;#62;,
    sv=0xa62ef0, flags=134) at perl.c:2731
#6  0x00007ffff5f274bb in faster_entersub (my_perl=&amp;#60;value optimized out&amp;#62;)
    at Faster.xs:47
#7  0x000000000044e1e6 in S_call_body (my_perl=0x74d010, myop=0xa161c0,
    is_eval=14 &amp;#39;&amp;#92;016&amp;#39;) at perl.c:2801
#8  0x00000000004539f6 in Perl_call_sv (my_perl=&amp;#60;value optimized out&amp;#62;,
    sv=0x851230, flags=150) at perl.c:2731
#9  0x0000000000463ef2 in Perl_sv_clear (my_perl=0x74d010, sv=0x85f260)
    at sv.c:4642
#10 0x00000000004646f5 in Perl_sv_free (my_perl=0x74d010, sv=0x85f260)
    at sv.c:4862
#11 0x0000000000460142 in S_visit (my_perl=0x74d010,
    f=0x476740 &amp;#60;do_clean_objs&amp;#62;, flags=524288, mask=524288) at sv.c:370
#12 0x000000000046019f in Perl_sv_clean_objs (my_perl=0x7ffff613ac4e)
    at sv.c:471
#13 0x0000000000455f48 in perl_destruct (my_perl=&amp;#60;value optimized out&amp;#62;)
    at perl.c:881
#14 0x0000000000421cb0 in main (argc=3, argv=0x7fffffffe2b8, env=0x7fffffffe2d8)
    at perlmain.c:111
&lt;/pre&gt;

			&lt;p&gt;まあ、このぐらいの操作おぼえとくだけでも、XS が犯人か Perl そのものが犯人かは判定が容易にできる。XS が犯人だってわかれば、その周辺があやしいってのがすぐわかるんで、再現するコードをつくって、作者に報告すればいい(パッチをつくれるとなおいい)。&lt;/p&gt;
			&lt;p&gt;なお、perl 本体のぶぶんの行数とか表示させるには -DDEBUGGING つきで perl をコンパイルしておくことが必要。&lt;/p&gt;
			&lt;p&gt;なお、これ以上くわしいつかいかたは、&lt;a href="http://d.hatena.ne.jp/stanaka/20080630/1214780557" target="_blank"&gt;http://d.hatena.ne.jp/stanaka/20080630/1214780557&lt;/a&gt; のへんを参考にするといいですね。&lt;/p&gt;
			&lt;p&gt;&lt;hr&gt;&lt;/p&gt;
			&lt;p&gt;なお Perl5 が SEGV する場合、1割は mod_perl に起因、9割5分は XS に起因、のこりの5分がperl本体に起因しています。ただし、のこりの5分のうち90%ぐらいはwell knownな問題です。&lt;a href="http://perl-users.jp/articles/crashing_perl.html" target="_blank"&gt;http://perl-users.jp/articles/crashing_perl.html&lt;/a&gt; このへんには目をとおしておくとよいです。&lt;/p&gt;
		&lt;/div&gt;
</content>
    <published>2010-02-05T09:10:21+09:00</published>
    <updated>2010-02-05T09:10:21+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100205/1265328621</id>
  </entry>
  <entry>
    <title>CPAN Testers 2.0 end-January update</title>
    <link rel="alternate" href="http://www.dagolden.com/index.php/661/cpan-testers-2-0-end-january-update/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">The bad news is that we’re still about two weeks behind schedule. The
good news is that we’re not falling further behind and in some areas,
we’re already ahead.

As I wrote in the last update, a number of my early-January tasks for
revising the Metabase libraries didn’t get done and were blocking
progress on other fronts. That work is now pretty much complete and I’m
ready to turn my attention to the actual migration of legacy reports into
a Metabase repository. Once that’s done, we’ll be able to test using it
to feed the cpantesters.org databases that Barbie has been preparing for
the conversion.

CPAN Testers 2.0 activity in the last couple weeks:

  * I revised Metabase framework libraries to separate user profile
    information and user authentication into separate facts. This also
    meant revising the user-profile generation program to match.

  * I implemented new Metabase::Resource classes to standardize
    extraction indexing data from Metabase::Fact resource strings. (E.g.
    cpan://distfile/DAGOLDEN/Capture-Tiny-0.07.tar.gz can be indexed
    under author “DAGOLDEN”, distribution name “Capture-Tiny”, and so
    on). This wasn’t on the plan, but I discovered that Ricardo and I had
    never actually gotten around to implementing, so it had to go from
    stubs to working code.

  * I confirmed that despite all the Metabase framework changes, I could
    still launch a local Metabase server and send CPAN::Reporter test
    reports via Test::Reporter::Transport::Metabase. (Thanks to Florian
    Ragwitz and Matt Trout for patches and guidance respectively on
    updating the Metabase web server for a more modern Catalyst runtime).

  * Barbie converted cpantesters.org backend databases to index on GUIDs
    instead of NNTP IDs. Existing legacy report had their NNTP IDs mapped
    to GUIDs.

  * Barbie and I agreed to have cpantesters.org get updates directly from
    the Amazon back-end rather than going through a web server. This
    postpones the need to implement search capability through the web
    until after launch.

The exact semantics of direct search against the back-end have yet to be
worked out, but I’ve decided to hold off on that until we have a Metabase
of historical records to experiment against.

At this point, the critical path is the conversion of old articles to the
Metabase and the deployment of a web server to inject new reports into
it. I’m working on the first, and hope to have both of those done by mid
Feb. That leaves us a tight two week period for testing, so stay tuned
for the next update.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>The bad news is that we’re still about two weeks behind schedule. The good news is that we’re not falling <em>further</em> behind and in some areas, we’re already ahead.</p>
<p>As I wrote in the <a href="http://www.dagolden.com/index.php/647/cpan-testers-2-0-mid-january-update/">last update</a>, a number of my early-January tasks for revising the Metabase libraries didn’t get done and were blocking progress on other fronts.  That work is now pretty much complete and I’m ready to turn my attention to the actual migration of legacy reports into a Metabase repository.  Once that’s done, we’ll be able to test using it to feed the cpantesters.org databases that Barbie has been preparing for the conversion.</p>
<p>CPAN Testers 2.0 activity in the last couple weeks:</p>
<ul>
<li>I revised Metabase framework libraries to separate user profile information and user authentication into separate facts.  This also meant revising the user-profile generation program to match.</li>
<li>I implemented new Metabase::Resource classes to standardize extraction indexing data from Metabase::Fact resource strings.  (E.g. cpan://distfile/DAGOLDEN/Capture-Tiny-0.07.tar.gz can be indexed under author “DAGOLDEN”, distribution name “Capture-Tiny”, and so on).  This wasn’t on the plan, but I discovered that Ricardo and I had never actually gotten around to implementing, so it had to go from stubs to working code.</li>
<li>I confirmed that despite all the Metabase framework changes, I could still launch a local Metabase server and send CPAN::Reporter test reports via Test::Reporter::Transport::Metabase.  (Thanks to Florian Ragwitz and Matt Trout for patches and guidance respectively on updating the Metabase web server for a more modern Catalyst runtime).</li>
<li>Barbie converted cpantesters.org backend databases to index on GUIDs instead of NNTP IDs.  Existing legacy report had their NNTP IDs mapped to GUIDs.</li>
<li>Barbie and I agreed to have cpantesters.org get updates directly from the Amazon back-end rather than going through a web server.  This postpones the need to implement search capability through the web until after launch.</li>
</ul>
<p>The exact semantics of direct search against the back-end have yet to be worked out, but I’ve decided to hold off on that until we have a Metabase of historical records to experiment against.  </p>
<p>At this point, the critical path is the conversion of old articles to the Metabase and the deployment of a web server to inject new reports into it.  I’m working on the first, and hope to have both of those done by mid Feb.  That leaves us a tight two week period for testing, so stay tuned for the next update.</p>
</div>
    </content>
    <category term="cpan-testers metabase perl-programming ironman"/>
    <published>2010-02-04T23:45:11Z</published>
    <updated>2010-02-04T23:45:11Z</updated>
    <author>
      <name>dagolden</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.dagolden.com/?p=661</id>
  </entry>
  <entry>
    <title>A Perl Programming Maintenance Checklist</title>
    <link rel="alternate" href="http://www.modernperlbooks.com/mt/2010/02/a-perl-programming-maintenance-checklist.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Polemic: anyone who believes that any specific general purpose
programming language is inherently unmaintainable has opinions on
software development worth ignoring.

Many people claim that the design of Perl 5 has such significant flaws
that render it far too difficult to write and maintain useful programs.
Many of the supporting arguments are syntactic preferences. "I don't like
sigils!" "Context make no senses to my!" "Real men don't need your sissy
curly braces to accompany our manly indentation!" "Isn't bless a little
bit cutesy for our Serious Enterprise Business Application?"

Other arguments... well, you've heard them.

Perl 5 has some design flaws, but I believe that syntax is such a small
part of maintainability that only the most facile discussions focus on
syntax to the exclusion of more important concerns. The next time you
have trouble maintaining a Perl 5 program, ask yourself:

  * Have I learned the language by reading documentation and working
    through tutorials, or am I fiddling with changing things by trial and
    error and guesswork and intuition based on experience in other
    languages?

  * Do I know how to use perldoc to look up builtins and language
    features?

  * Have I skimmed the Perl FAQ included in every Perl 5 distribution?

  * Have I used Perl::Tidy to unify the formatting into a consistent
    style?

  * Do I know the difference between void, scalar, and list context? Can
    I identify them?

  * 

  * Do I know how to use B::Deparse to explain the evaluation plan of
    complex constructs?

  * Does this program have a set of automated tests I can trust?

  * Did the original programmer understand the problem domain? Do I?

  * Did the original programmer "borrow" this code from elsewhere, change
    a few lines, and add a modified copyright statement?

  * Did this program grow from a throwaway idea into a critical business
    component without planning, design, or refactoring?

  * Is the original author available to answer questions, whether in
    person or through some sort of design notes?

  * Is the program well-factored?

  * Does the program include appropriate documentation for its purpose,
    its major systems, its APIs, and any surprising design decisions?

  * Do I have a clear understanding of what the program does and why?

  * Does the program have a modular design, with well-enforced
    encapsulation boundaries between components?

  * Can I configure and build the program on my local system?

  * Can I deploy it?

  * Does the code show examples of idiomatic programming from authors
    fluent in the language, or is it a pastiche of styles cribbed from
    documentation and witch-doctor expermentation?

  * Did the original author know how to program in any language?

  * Did the original author take advantage of obvious strengths of the
    host language in appropriate ways (or did he distrust arrays and
    continually write to and read from a temporary file instead—I have
    seen this with my own eyes, and the host language was not Perl)?

  * Does the program take advantage of well-known and trustworthy
    external libraries?

  * Does the build process spew compiler errors and warnings? Does the
    program spew warnings and errors when deployed?

  * Does the program contain obvious repetition and near repetition?

  * Would you be proud of writing the program in six months?

Note how few of these concerns have anything to do with Perl—and, of
those that do, trivial rewording would make them appropriate for other
languages.</div>
    </summary>
    <content type="html">
        &lt;p&gt;Polemic: anyone who believes that any specific general purpose programming language is inherently unmaintainable has opinions on software development worth ignoring.&lt;/p&gt;

&lt;p&gt;Many people claim that the design of Perl 5 has such significant flaws that render it far too difficult to write and maintain useful programs.  Many of the supporting arguments are syntactic preferences.  "I don't like sigils!"  "Context make no senses to my!"  "Real men don't need your sissy curly braces to accompany our manly indentation!"  "Isn't &lt;code&gt;bless&lt;/code&gt; a little bit cutesy for our Serious Enterprise Business Application?"&lt;/p&gt;

&lt;p&gt;Other arguments... well, you've heard them.&lt;/p&gt;

&lt;p&gt;Perl 5 has some design flaws, but I believe that syntax is such a small part of maintainability that only the most facile discussions focus on syntax to the exclusion of more important concerns.  The next time you have trouble maintaining a Perl 5 program, ask yourself:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Have I learned the language by reading documentation and working through tutorials, or am I fiddling with changing things by trial and error and guesswork and intuition based on experience in other languages?&lt;/li&gt;

&lt;li&gt;Do I know how to use &lt;code&gt;perldoc&lt;/code&gt; to look up builtins and language features?&lt;/li&gt;

&lt;li&gt;Have I skimmed the Perl FAQ included in every Perl 5 distribution?&lt;/li&gt;

&lt;li&gt;Have I used &lt;a href="http://search.cpan.org/perldoc?Perl::Tidy"&gt;Perl::Tidy&lt;/a&gt; to unify the formatting into a consistent style?&lt;/li&gt;

&lt;li&gt;Do I know the difference between void, scalar, and list context?  Can I identify them?&lt;li&gt;

&lt;li&gt;Do I know how to use &lt;a href="http://search.cpan.org/perldoc?B::Deparse"&gt;B::Deparse&lt;/a&gt; to explain the evaluation plan of complex constructs?&lt;/li&gt;

&lt;li&gt;Does this program have a set of automated tests I can trust?&lt;/li&gt;

&lt;li&gt;Did the original programmer understand the problem domain?  Do I?&lt;/li&gt;

&lt;li&gt;Did the original programmer "borrow" this code from elsewhere, change a few lines, and add a modified copyright statement?&lt;/li&gt;

&lt;li&gt;Did this program grow from a throwaway idea into a critical business component without planning, design, or refactoring?&lt;/li&gt;

&lt;li&gt;Is the original author available to answer questions, whether in person or
through some sort of design notes?&lt;/li&gt;

&lt;li&gt;Is the program well-factored?&lt;/li&gt;

&lt;li&gt;Does the program include appropriate documentation for its purpose, its major systems, its APIs, and any surprising design decisions?&lt;/li&gt;

&lt;li&gt;Do I have a clear understanding of what the program does and why?&lt;/li&gt;

&lt;li&gt;Does the program have a modular design, with well-enforced encapsulation
boundaries between components?&lt;/li&gt;

&lt;li&gt;Can I configure and build the program on my local system?&lt;/li&gt;

&lt;li&gt;Can I deploy it?&lt;/li&gt;

&lt;li&gt;Does the code show examples of idiomatic programming from authors fluent in the language, or is it a pastiche of styles cribbed from documentation and witch-doctor expermentation?&lt;/li&gt;

&lt;li&gt;Did the original author know how to program in &lt;em&gt;any&lt;/em&gt; language?&lt;/li&gt;

&lt;li&gt;Did the original author take advantage of obvious strengths of the host language in appropriate ways (or did he distrust arrays and continually write to and read from a temporary file instead&amp;mdash;I have seen this with my own eyes, and the host language was &lt;em&gt;not&lt;/em&gt; Perl)?&lt;/li&gt;

&lt;li&gt;Does the program take advantage of well-known and trustworthy external libraries?&lt;/li&gt;

&lt;li&gt;Does the build process spew compiler errors and warnings?  Does the program spew warnings and errors when deployed?&lt;/li&gt;

&lt;li&gt;Does the program contain obvious repetition and near repetition?&lt;/li&gt;

&lt;li&gt;Would you be proud of writing the program in six months?&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Note how few of these concerns have anything to do with Perl&amp;mdash;and, of
those that do, trivial rewording would make them appropriate for other
languages.&lt;/p&gt;

        
    </content>
    <category term="maintainability modern perl perl 5 perl programming software development"/>
    <published>2010-02-04T21:52:38Z</published>
    <updated>2010-02-04T21:52:38Z</updated>
    <author>
      <name>chromatic</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:www.modernperlbooks.com,2010:/mt//1.146</id>
  </entry>
  <entry>
    <title>Gearman (6) — рекурсивные воркеры</title>
    <link rel="alternate" href="http://onperl.ru/onperl/2010/02/gearman-6-rekursivnie-vorkeri.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">В фильме «13-й этаж» описывалась ситуация, когда смоделированный в
компьютере мир создал свой собственный искусственный мир. При работе с
Gearman можно столкнуться с задачами, которые в свою очередь удобно
разбивать на части и отдавать на обработку следующим воркерам. Причем
передача возможна в том числе тому же методу воркера, из которого она
инициирована.

Вот пример. У нас есть сервис, отыскивающий по названию город в базе
данных. Атомарная работа — поиск города — задача, вынесенная в отдельный
воркер. При этом воркер умеет самостоятельно обрабатывать запрос,
состоящий из нескольких слов:

my @words = $request =~ m{(\w+)}g;
for my $word (@words) {
place_locality_search_word($word, $response);
}

Если в нашем распоряжении есть достаточное число свободных воркеров (и
вычислительные мощности), то этот цикл ничего не мешает переписать так,
чтобы он циклически выставлял новые задачи, каждая на отдельное слово.
Воркер обязан проверить, что ему передано, и если запрос содержит одно
слово, то обработать его самостоятельно.

Важно не забывать, что такая схема требует наличия как минимум двух
воркеров (один может быть и занятым при получении начального задания).

На картинке — тестовый результат работы такого рекурсивного механизма для
запроса со списком городов с ближайшими Perl-мероприятиями (софия
екатеринбург амстердам москва киев vlorë).

[IMAGE]

P. S. Пока не стал коммитить такое решение :-)</div>
    </summary>
    <content type="html">
        &lt;p&gt;В&amp;nbsp;фильме «&lt;a href="http://www.imdb.com/title/tt0139809/"&gt;13-й этаж&lt;/a&gt;» описывалась ситуация, когда смоделированный в компьютере мир создал свой собственный искусственный мир. При работе с &lt;a href="http://gearman.org"&gt;Gearman&lt;/a&gt; можно столкнуться с задачами, которые в свою очередь удобно разбивать на части и отдавать на обработку следующим воркерам. Причем передача возможна&amp;nbsp;в том числе тому же методу воркера, из которого она инициирована.&lt;/p&gt;
&lt;p&gt;Вот пример. У нас есть сервис, отыскивающий по названию город в базе данных. Атомарная работа — поиск города — задача, вынесенная в отдельный воркер. При этом воркер умеет самостоятельно обрабатывать запрос, состоящий из нескольких слов:&lt;/p&gt;&lt;tt&gt;
&lt;p&gt;my @words = $request =~ m{(\w+)}g;&lt;br /&gt;for my $word (@words) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; place_locality_search_word($word, $response);&lt;br /&gt;}&lt;/p&gt;&lt;/tt&gt;
&lt;p&gt;Если в нашем распоряжении есть достаточное число свободных воркеров (и вычислительные мощности), то этот цикл ничего не мешает переписать так, чтобы он циклически выставлял новые задачи, каждая на отдельное слово. Воркер обязан проверить, что ему передано, и если запрос содержит одно слово, то обработать его самостоятельно.&lt;/p&gt;
&lt;p&gt;Важно не забывать, что такая схема требует наличия как минимум двух воркеров (один может быть и занятым при получении начального задания).&lt;/p&gt;
&lt;p&gt;На картинке — тестовый результат работы такого рекурсивного механизма для запроса со списком городов с ближайшими Perl-мероприятиями &lt;em&gt;(софия екатеринбург амстердам москва киев vlorë).&lt;/em&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://img.onperl.ru/cities.gif"&gt;&lt;/p&gt;
&lt;p&gt;P. S. Пока не стал коммитить такое решение :-)&lt;/p&gt;
        
    </content>
    <category term="Приложения dispatch gearman parallel"/>
    <published>2010-02-04T21:58:35+01:00</published>
    <updated>2010-02-04T21:58:35+01:00</updated>
    <author>
      <name>ash</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:onperl.ru,2010:/onperl//1.130</id>
  </entry>
  <entry>
    <title>Access MS SQL Server from UNIX in ten minutes</title>
    <link rel="alternate" href="http://www.martin-evans.me.uk/node/55" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">In this example for Linux we will install the unixODBC driver manager and
an ODBC Driver and get data back from Microsoft SQL Server. We are
ignoring access from any particular programming language or interface and
just use the isql utility that comes with unixODBC but for further
information about access from PHP, Perl, Python etc see
Easysoft development.

You will need to know:

  1. the name or IP address of the machine where MS SQL Server is
    installed.

read more</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>In this example for Linux we will install the unixODBC driver manager and an ODBC Driver and get data back from Microsoft SQL Server. We are ignoring access from any particular programming language or interface and just use the isql utility that comes with unixODBC but for further information about access from PHP, Perl, Python etc see<br/>
<a href="http://www.easysoft.com/developer/index.html">Easysoft development</a>.</p>
<p>You will need to know:</p>
<ol>
<li>the name or IP address of the machine where MS SQL Server is installed.</li>
</ol><p><a href="http://www.martin-evans.me.uk/node/55" target="_blank">read more</a></p></div>
    </content>
    <published>0</published>
    <updated>0</updated>
    <author>
      <name>martinjevans</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:55 at http://www.martin-evans.me.uk</id>
  </entry>
  <entry>
    <title>Installing Net::Amazon::S3 Perl module on an Ubuntu server</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/andrewault/~3/aaMl4BLHv74/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">The following is the same on recent Ubuntu releases, including Karmic
Koala.

What will not work

There seems to be a problem if you install Net::Amazon::S3 from CPAN.
This will not work:

sudo cpan Net::Amazon::S3

Just about every dependency in the world installs, but fails in the home
stretch when XML::LibXML::XPathContext and XML::LibXML fail to install.

What will work

sudo aptitude install libnet-amazon-s3-perl
sudo cpan Net::Amazon::S3::Client

Test your install with this

After throwing some data into S3 with S3Fox, test your installation. You
will need to set values for aws_access_key_id and aws_secret_access_key,
of course.

#!/usr/bin/perl
use warnings;
use strict;
use Net::Amazon::S3;
use Net::Amazon::S3::Client;

my %s3_hash = (
                                aws_access_key_id     =&gt; "XXXXXXXXXXXXXXXXX",
                                aws_secret_access_key =&gt; "YYYYYYYYYYYYYYYYYYYYYYYYYY",
                                retry                 =&gt; 1,
);

my $s3 = Net::Amazon::S3-&gt;new( \%s3_hash );
my $client = Net::Amazon::S3::Client-&gt;new( s3 =&gt; $s3 );

my @buckets = $client-&gt;buckets;
foreach my $bucket (@buckets) {
        print $bucket-&gt;name . "\n";
}

share and enjoy: Print Digg Sphinn del.icio.us Facebook Mixx
Google Bookmarks Blogplay Fark Reddit Slashdot StumbleUpon Twitter

[IMAGE]
[IMAGE]

[IMAGE]</div>
    </summary>
    <content type="html">&lt;p&gt;The following is the same on recent Ubuntu releases, including Karmic Koala.&lt;/p&gt;
&lt;h4&gt;What will not work&lt;/h4&gt;
&lt;p&gt;There seems to be a problem if you install Net::Amazon::S3 from CPAN. This will not work:&lt;/p&gt;
&lt;pre class="brush: php"&gt;
sudo cpan Net::Amazon::S3
&lt;/pre&gt;
&lt;p&gt;Just about every dependency in the world installs, but fails in the home stretch when XML::LibXML::XPathContext and XML::LibXML fail to install.&lt;/p&gt;
&lt;h4&gt;What will work&lt;/h4&gt;
&lt;pre class="brush: php"&gt;
sudo aptitude install libnet-amazon-s3-perl
sudo cpan Net::Amazon::S3::Client
&lt;/pre&gt;
&lt;h4&gt;Test your install with this&lt;/h4&gt;
&lt;p&gt;After throwing some data into S3 with S3Fox, test your installation. You will need to set values for aws_access_key_id and aws_secret_access_key, of course.&lt;/p&gt;
&lt;pre class="brush: php"&gt;
#!/usr/bin/perl
use warnings;
use strict;
use Net::Amazon::S3;
use Net::Amazon::S3::Client;

my %s3_hash = (
				aws_access_key_id     =&amp;gt; &amp;quot;XXXXXXXXXXXXXXXXX&amp;quot;,
				aws_secret_access_key =&amp;gt; &amp;quot;YYYYYYYYYYYYYYYYYYYYYYYYYY&amp;quot;,
				retry                 =&amp;gt; 1,
);

my $s3 = Net::Amazon::S3-&amp;gt;new( \%s3_hash );
my $client = Net::Amazon::S3::Client-&amp;gt;new( s3 =&amp;gt; $s3 );

my @buckets = $client-&amp;gt;buckets;
foreach my $bucket (@buckets) {
	print $bucket-&amp;gt;name . &amp;quot;\n&amp;quot;;
}
&lt;/pre&gt;



share and enjoy:


	&lt;a rel="nofollow" href="http://www.printfriendly.com/print?url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;partner=sociable" title="Print"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/printfriendly.png" alt="Print"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://digg.com/submit?phase=2&amp;amp;url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server&amp;amp;bodytext=The%20following%20is%20the%20same%20on%20recent%20Ubuntu%20releases%2C%20including%20Karmic%20Koala.%0D%0A%0D%0AWhat%20will%20not%20work%0D%0A%0D%0AThere%20seems%20to%20be%20a%20problem%20if%20you%20install%20Net%3A%3AAmazon%3A%3AS3%20from%20CPAN.%20This%20will%20not%20work%3A%0D%0A%0D%0A%5Bsourcecode%5D%0D%0Asudo%20cpan%20Net%3A%3AAmazon%3A%3AS3%0D%0A%5B%2Fsourcecode%5D%0D" title="Digg"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/digg.png" alt="Digg"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://sphinn.com/index.php?c=post&amp;amp;m=submit&amp;amp;link=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F" title="Sphinn"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/sphinn.png" alt="Sphinn"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://delicious.com/post?url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server&amp;amp;notes=The%20following%20is%20the%20same%20on%20recent%20Ubuntu%20releases%2C%20including%20Karmic%20Koala.%0D%0A%0D%0AWhat%20will%20not%20work%0D%0A%0D%0AThere%20seems%20to%20be%20a%20problem%20if%20you%20install%20Net%3A%3AAmazon%3A%3AS3%20from%20CPAN.%20This%20will%20not%20work%3A%0D%0A%0D%0A%5Bsourcecode%5D%0D%0Asudo%20cpan%20Net%3A%3AAmazon%3A%3AS3%0D%0A%5B%2Fsourcecode%5D%0D" title="del.icio.us"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/delicious.png" alt="del.icio.us"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;t=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server" title="Facebook"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/facebook.png" alt="Facebook"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server" title="Mixx"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/mixx.png" alt="Mixx"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server&amp;amp;annotation=The%20following%20is%20the%20same%20on%20recent%20Ubuntu%20releases%2C%20including%20Karmic%20Koala.%0D%0A%0D%0AWhat%20will%20not%20work%0D%0A%0D%0AThere%20seems%20to%20be%20a%20problem%20if%20you%20install%20Net%3A%3AAmazon%3A%3AS3%20from%20CPAN.%20This%20will%20not%20work%3A%0D%0A%0D%0A%5Bsourcecode%5D%0D%0Asudo%20cpan%20Net%3A%3AAmazon%3A%3AS3%0D%0A%5B%2Fsourcecode%5D%0D" title="Google Bookmarks"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/googlebookmark.png" alt="Google Bookmarks"&gt;&lt;/a&gt;
	&lt;a href="http://blogplay.com" title="Blogplay"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/blogplay.png" alt="Blogplay"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://cgi.fark.com/cgi/fark/farkit.pl?h=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server&amp;amp;u=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F" title="Fark"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/fark.png" alt="Fark"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server" title="Reddit"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/reddit.png" alt="Reddit"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://slashdot.org/bookmark.pl?title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server&amp;amp;url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F" title="Slashdot"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/slashdot.png" alt="Slashdot"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F&amp;amp;title=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server" title="StumbleUpon"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/stumbleupon.png" alt="StumbleUpon"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" href="http://twitter.com/home?status=Installing%20Net%3A%3AAmazon%3A%3AS3%20Perl%20module%20on%20an%20Ubuntu%20server%20-%20http%3A%2F%2Fwww.andrewault.net%2F2010%2F02%2F04%2Finstalling-netamazons3-perl-module-on-an-ubuntu-server%2F" title="Twitter"&gt;&lt;img src="http://www.andrewault.net/wp-content/plugins/sociable/images/twitter.png" alt="Twitter"&gt;&lt;/a&gt;


&lt;br/&gt;&lt;br/&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tRqyR60zCq6u0R2qW_1VUsQUQUE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tRqyR60zCq6u0R2qW_1VUsQUQUE/0/di"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tRqyR60zCq6u0R2qW_1VUsQUQUE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tRqyR60zCq6u0R2qW_1VUsQUQUE/1/di"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/andrewault/~4/aaMl4BLHv74"&gt;</content>
    <category term="admin perl ubuntu server cpan ubuntu"/>
    <published>2010-02-04T20:17:33Z</published>
    <updated>2010-02-04T20:17:33Z</updated>
    <author>
      <name>admin</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.andrewault.net/?p=208</id>
  </entry>
  <entry>
    <title>Perl script para calcular el page rank</title>
    <link rel="alternate" href="http://www.perlhispano.com/cgi-bin/index.cgi?action=viewnews&amp;id=34" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"> Hola gente acá les dejo un script de perl muy bueno para evaluar el page
rank de un sitio.

http://www.solucionesroot.com/descargas/archivos/page_rank-1.0.tar.gz

Cortesía de John Walker un abrazo para el.

Yo lo uso para ...</div>
    </summary>
    <content type="text">
      Hola gente acá les dejo un script de perl muy bueno para evaluar el page rank de un sitio. &lt;br&gt; &lt;br&gt;&lt;a href="http://www.solucionesroot.com/descargas/archivos/page_rank-1.0.tar.gz" target="_blank"&gt;&lt;a href="http://www.solucionesroot.com/descargas/archivos/page_rank-1.0.tar.gz" target="_blank"&gt;http://www.solucionesroot.com/descargas/archivos/page_rank-1.0.tar.gz&lt;/a&gt;&lt;/a&gt; &lt;br&gt; &lt;br&gt;Cortesía de John Walker un abrazo para el. &lt;br&gt; &lt;br&gt;Yo lo uso para ...
    </content>
    <category term="Miscelanea"/>
    <published>2010-02-04T12:46:42-05:00</published>
    <updated>2010-02-04T12:46:42-05:00</updated>
    <author>
      <name>Webmaster</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.perlhispano.com/cgi-bin/index.cgi?action=viewnews&amp;id=34</id>
  </entry>
  <entry>
    <title>Blast from the past: E02</title>
    <link rel="alternate" href="http://use.perl.org/~masak/journal/40159?from=rss" type="text/html"/>
    <summary type="text">SF took my challenge to heart and started producing a "modern Perl 6"
version of the example code in E02. His thought process can be seen here,
and here.

After being a bystander for a few hours, I coulndn't restrain myself
anymore: I produced my own version. I should say at once that it's quite
different from SF's: while he keeps close to the original E02 (which, in
turn, sets out to prove that Perl 6 is/was not very different from Perl
5), my version is a bit more liberal in its interpretation. I do mix in
some of my personal preferences into it. Some examples:

  * We don't do $ARGS prompts("Search? ") anymore, but there's a nice
    &amp;prompt function which I used instead, together with a while loop.

  * The &amp;show function now uses gather/take, rather than printing
    directly.

  * Also, I avoided the statement-modifying mess from the original E02
    &amp;show code.

  * Also, E02's &amp;show makes a point of using a slurpy @_ rather than
    naming the paramters. I don't. (Neither does SF.)

  * It just makes sense to use a given/when construct in the &amp;insert
    function. To its credit, E02 tantalizingly hints of it, but then does
    a MIB mind-wipe. (You don't recall that bit? Oh well...)

  * In the same function, E02 puts undef to initiate the child nodes to
    some empty value. Both SF and I independently realized that just any
    undefined value won't work if &amp;insert is to have %tree in the
    signature, because %tree only binds to an Associative value. SF
    solved it by putting Hash (an undefined Hash type object) in the
    child nodes, and changed it to Hash.new in the later version. I used
    {}, which should be equivalent to Hash.new, but IMHO more idiomatic.

  * The whole traits business hadn't solidified in 2002, but I believe
    that the end result is both more realiable, more useful, and
    prettier. You'll have to judge for yourself.

I believe rewriting the exigeses in modern form is a very worthy
activity. I hope we'll see more of that. Perl 6 suffers a bit from stale,
outdated documentation, and having these in new versions would be
valuable.

It's also a very interesting historical activity to read the old
apocalypses and exigeses, as I increasingly find. Perl 6 has come a long,
long way since 2001.</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>SF took <a href="http://irclog.perlgeek.de/perl6/2010-02-03#i_1954377">my challenge</a> to heart and started producing a "modern Perl 6" version of the example code in <a href="http://dev.perl.org/perl6/doc/design/exe/E02.html">E02</a>. His thought process can be seen <a href="http://lastofthecarelessmen.blogspot.com/2010/02/binary-tree.html">here</a>, and <a href="http://lastofthecarelessmen.blogspot.com/2010/02/binary-tree-almost-complete-script.html">here</a>.</p>
        <p>After being a bystander for a few hours, I coulndn't restrain myself anymore: I produced <a href="http://gist.github.com/294621">my own version</a>. I should say at once that it's quite different from SF's: while he keeps close to the original <a href="http://dev.perl.org/perl6/doc/design/exe/E02.html">E02</a> (which, in turn, sets out to prove that Perl 6 is/was not very different from Perl 5), my version is a bit more liberal in its interpretation. I do mix in some of my personal preferences into it. Some examples:</p>
        <ul>
  <li>We don't do <code>$ARGS prompts("Search? ")</code> anymore, but there's a nice <code>&amp;prompt</code> function which I used instead, together with a <code>while</code> loop.</li><li>The <code>&amp;show</code> function now uses <code>gather/take</code>, rather than printing directly.</li><li>Also, I avoided the statement-modifying mess from the original E02 <code>&amp;show</code> code.</li><li>Also, E02's <code>&amp;show</code> makes a point of using a slurpy <code>@_</code> rather than naming the paramters. I don't. (Neither does SF.)</li><li>It just makes sense to use a <code>given/when</code> construct in the <code>&amp;insert</code> function. To its credit, E02 tantalizingly hints of it, but then does a MIB mind-wipe. (You don't recall that bit? Oh well...)</li><li>In the same function, E02 puts <code>undef</code> to initiate the child nodes to some empty value. Both SF and I independently realized that just any undefined value won't work if <code>&amp;insert</code> is to have <code>%tree</code> in the signature, because <code>%tree</code> only binds to an <code>Associative</code> value. SF solved it by putting <code>Hash</code> (an undefined <code>Hash</code> type object) in the child nodes, and changed it to <code>Hash.new</code> in the later version. I used <code>{}</code>, which should be equivalent to <code>Hash.new</code>, but IMHO more idiomatic.</li><li>The whole traits business hadn't solidified in 2002, but I believe that the end result is both more realiable, more useful, and prettier. You'll have to judge for yourself.</li></ul>
        <p>I believe rewriting the exigeses in modern form is a very worthy activity. I hope we'll see more of that. Perl 6 suffers a bit from stale, outdated documentation, and having these in new versions would be valuable.</p>
        <p>It's also a very interesting <em>historical</em> activity to read the old apocalypses and exigeses, as I increasingly find. Perl 6 has come a long, long way since 2001.</p>
      </div>
    </content>
    <category term="perl6"/>
    <published>2010-02-04T14:47:06Z</published>
    <updated>2010-02-04T14:47:06Z</updated>
    <author>
      <name>masak</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://use.perl.org/~masak/journal/40159?from=rss</id>
  </entry>
  <entry>
    <title>Faster.pm の中身の話</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/tokuhirom/20100204/1265286603" type="text/html"/>
    <summary type="text">mlehmann の Faster.pm という Perl 用 JIT があるのだが、これの仕組み。

  *  op_entersub をフックする

  *  op_entersub にはいるタイミングで発動!

      *  op tree を C のコードに変換する

      *  cc する

      *  dynaloader でよみこむ

といった具合。基本的には Shibuya.pm で発表済のだれでもしっているようなテクニックをつかっている。

これはだいたい 20% ぐらいはやくなるらしい。まあ妥当なかんじか。とはいえテストとおらないしまともにうごかないので、本当かどうかはわからない。

結局 run_ops まわりの部分がインラインで最適化されるという点におけるメリットぐらいで、各 opcode
の操作はそれぞれの中でやっているわけだから、納得できる数字かとおもう。ただ、実際にそのテストにつかったコードってのがないんで、なんともいえないけど。

実用という点で評価した場合、Faster.pm は op_entersub をフックしているのがきびしい。せめて lexical scope
でうごくか、optimize(\&amp;code) のような形式になる方が使いやすいのではないか。</summary>
    <content type="html">
		&lt;div class="section"&gt;
			&lt;p&gt;mlehmann の Faster.pm という Perl 用 JIT があるのだが、これの仕組み。&lt;/p&gt;
			&lt;ul&gt;
				&lt;li&gt; op_entersub をフックする&lt;/li&gt;
				&lt;li&gt; op_entersub にはいるタイミングで発動!
				&lt;ul&gt;
					&lt;li&gt; op tree を C のコードに変換する&lt;/li&gt;
					&lt;li&gt; cc する&lt;/li&gt;
					&lt;li&gt; dynaloader でよみこむ&lt;/li&gt;
				&lt;/ul&gt;
				&lt;/li&gt;
			&lt;/ul&gt;
			&lt;p&gt;といった具合。基本的には Shibuya.pm で発表済のだれでもしっているようなテクニックをつかっている。&lt;/p&gt;
			&lt;p&gt;これはだいたい 20% ぐらいはやくなるらしい。まあ妥当なかんじか。とはいえテストとおらないしまともにうごかないので、本当かどうかはわからない。&lt;/p&gt;
			&lt;p&gt;結局 run_ops まわりの部分がインラインで最適化されるという点におけるメリットぐらいで、各 opcode の操作はそれぞれの中でやっているわけだから、納得できる数字かとおもう。ただ、実際にそのテストにつかったコードってのがないんで、なんともいえないけど。&lt;/p&gt;
			&lt;p&gt;実用という点で評価した場合、Faster.pm は op_entersub をフックしているのがきびしい。せめて lexical scope でうごくか、optimize(\&amp;code) のような形式になる方が使いやすいのではないか。&lt;/p&gt;
		&lt;/div&gt;
</content>
    <published>2010-02-04T21:30:03+09:00</published>
    <updated>2010-02-04T21:30:03+09:00</updated>
    <author>
      <name>tokuhirom</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/tokuhirom/20100204/1265286603</id>
  </entry>
  <entry>
    <title>Binary Tree, Almost Complete Script</title>
    <link rel="alternate" href="http://lastofthecarelessmen.blogspot.com/2010/02/binary-tree-almost-complete-script.html" type="text/html"/>
    <summary type="text">So, I played around with the binary tree script a bit more after posting
yesterday. It was mostly very straightforward once I figured out how to
make it work with "is rw". Here's what I've got now:

# bintree - binary tree demo program 
# adapted from "Perl Cookbook", Recipe 11.15
# converted to modern Perl 6 by SF
use v6;

my %root;
for (1..1000).pick(20) {
    insert(%root, $_);
}

enum TraversalMode &lt;pre in post&gt;;

print "Pre order:  "; show(%root, TraversalMode::pre);  print "\n";
print "In order:   "; show(%root, TraversalMode::in);   print "\n";
print "Post order: "; show(%root, TraversalMode::post); print "\n";

#        $ARGS prompts("Search? ");

for @*ARGS {
    if (my $node = search(%root, $_)) {
        say "Found $_ at { $node.perl }: { $node&lt;VALUE&gt; }";
        # say "(again!)" if $node&lt;VALUE&gt;.Found &gt; 1;
    }
    else {
        say "No $_ in tree";
    }
}

#########################################
sub insert(Hash $tree is rw, Int $val) {
    unless $tree {
        $tree&lt;LEFT&gt;   = Hash.new;
        $tree&lt;RIGHT&gt;  = Hash.new;
        $tree&lt;VALUE&gt;  = $val ; # but Found(0);
        return;
    }
    if    ($tree&lt;VALUE&gt; &gt; $val) { insert($tree&lt;LEFT&gt;,  $val) }
    elsif ($tree&lt;VALUE&gt; &lt; $val) { insert($tree&lt;RIGHT&gt;, $val) }
    else                        { warn "dup insert of $val\n" }
}

sub show(%tree, $mode) {
    return unless %tree;
    show(%tree&lt;LEFT&gt;, $mode) unless $mode == TraversalMode::post;
    show(%tree&lt;RIGHT&gt;,$mode)     if $mode == TraversalMode::pre;
    print %tree&lt;VALUE&gt;, " ";
    show(%tree&lt;LEFT&gt;, $mode)     if $mode == TraversalMode::post;
    show(%tree&lt;RIGHT&gt;,$mode) unless $mode == TraversalMode::pre;
}
     
sub search ($tree is rw, $value) {
    return unless $tree;
    return search($tree{$value &lt; $tree&lt;VALUE&gt; ?? "LEFT" !! "RIGHT"}, $value)
        unless $tree&lt;VALUE&gt; == $value;
    # $tree&lt;VALUE&gt; but Found($tree&lt;VALUE&gt;.Found+1);
    return $tree;
}


Let me highlight the big differences between this and the Exegesis 2
version:

1) Using pick instead of rand. It's not shorter, but IMO pick is
definitely more idiomatic. pick is also more correct, in some sense: the
original code clearly did not want duplicate numbers, warning the user
when they happened. With pick that never happens.

2) enum instead of trying to emulate the idea with is constant = (0..2).

3) Oh yes, using %root instead of $root.

4) Apparently $ARGS prompts("Search? "); was meant to create a prompt to
get input from the user if there's nothing on the command line? I've no
idea if that facility still exists in Perl 6, or was ever implemented in
Rakudo.

5) Also skipped the Found role. I'm not sure how the old code expected it
work without defining Found. I think they were trying to prove a point
about roles, because the whole idea would be more easily implemented
using another field in the hash.

6) In insert, instead of sticking undef in the left and right fields, I
actually create empty Hash objects. As you can see in my last post, I
originally created undefined Hash objects, but this worked better for me.
In practice, it might be better to leave these out entirely until they
are needed, but this matches the logic of the old version.

7) In show, I've converted it to use sub arguments rather than all that
ugly @_ stuff. I've no idea why the original code didn't do that in the
first place, unless it was to show that @_ still worked.

8) In search, I've changed it from a boolean logical expression to a
simple ternary ?? !!.

I guess I should look at coding up a Found role, and then trying to use
it correctly. Thought honestly, I'm more inclined to completely rewrite
this as a binary tree class, which I think would do wonders for the code
even as it wandered far away from the shape of the original.</summary>
    <content type="text">So, I played around with the binary tree script a bit more after posting yesterday.  It was mostly very straightforward once I figured out how to make it work with "is rw".  Here's what I've got now:&lt;br /&gt;&lt;pre&gt;&lt;span&gt;# bintree - binary tree demo program &lt;/span&gt;&lt;br /&gt;&lt;span&gt;# adapted from &amp;quot;Perl Cookbook&amp;quot;, Recipe 11.15&lt;/span&gt;&lt;br /&gt;&lt;span&gt;# converted to modern Perl 6 by SF&lt;/span&gt;&lt;br /&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;v&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;my&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;;&lt;br /&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pick&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;enum&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;pre in post&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;Pre order:  &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;; &lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;pre&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;;  &lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;In order:   &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;; &lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;;   &lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;Post order: &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;; &lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;; &lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;#        $ARGS prompts(&amp;quot;Search? &amp;quot;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;ARGS&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;my&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;search&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;Found &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt; at &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;perl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# say &amp;quot;(again!)&amp;quot; if $node&amp;lt;VALUE&amp;gt;.Found &amp;gt; 1;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;No &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt; in tree&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;#########################################&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Hash&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rw&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;unless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Hash&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Hash&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# but Found(0);&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;elsif&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;dup insert of &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;nless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;nless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;pre&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;show&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;nless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;mode&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TraversalMode&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;pre&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;search&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rw&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;nless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;search&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;??&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;nless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# $tree&amp;lt;VALUE&amp;gt; but Found($tree&amp;lt;VALUE&amp;gt;.Found+1);&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Let me highlight the big differences between this and the &lt;a href="http://dev.perl.org/perl6/doc/design/exe/E02.html"&gt;Exegesis 2 version&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;1) Using &lt;code&gt;pick&lt;/code&gt; instead of &lt;code&gt;rand&lt;/code&gt;.  It's not shorter, but IMO &lt;code&gt;pick&lt;/code&gt; is definitely more idiomatic.  &lt;code&gt;pick&lt;/code&gt; is also more correct, in some sense: the original code clearly did not want duplicate numbers, warning the user when they happened.  With &lt;code&gt;pick&lt;/code&gt; that never happens.&lt;br /&gt;&lt;br /&gt;2) enum instead of trying to emulate the idea with &lt;code&gt;is constant = (0..2)&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;3) Oh yes, using &lt;code&gt;%root&lt;/code&gt; instead of &lt;code&gt;$root&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;4) Apparently &lt;code&gt;$ARGS prompts("Search? ");&lt;/code&gt; was meant to create a prompt to get input from the user if there's nothing on the command line?  I've no idea if that facility still exists in Perl 6, or was ever implemented in Rakudo.&lt;br /&gt;&lt;br /&gt;5) Also skipped the Found role.  I'm not sure how the old code expected it work without defining Found.  I think they were trying to prove a point about roles, because the whole idea would be more easily implemented using another field in the hash.&lt;br /&gt;&lt;br /&gt;6) In &lt;code&gt;insert&lt;/code&gt;, instead of sticking &lt;code&gt;undef&lt;/code&gt; in the left and right fields, I actually create empty Hash objects.  As you can see in my last post, I originally created undefined Hash objects, but this worked better for me.  In practice, it might be better to leave these out entirely until they are needed, but this matches the logic of the old version.&lt;br /&gt;&lt;br /&gt;7) In &lt;code&gt;show&lt;/code&gt;, I've converted it to use sub arguments rather than all that ugly &lt;code&gt;@_&lt;/code&gt; stuff.  I've no idea why the original code didn't do that in the first place, unless it was to show that &lt;code&gt;@_&lt;/code&gt; still worked.&lt;br /&gt;&lt;br /&gt;8) In &lt;code&gt;search&lt;/code&gt;, I've changed it from a boolean logical expression to a simple ternary &lt;code&gt;?? !!&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;I guess I should look at coding up a Found role, and then trying to use it correctly.  Thought honestly, I'm more inclined to completely rewrite this as a binary tree class, which I think would do wonders for the code even as it wandered far away from the shape of the original.&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="Perl 6"/>
    <published>2010-02-04T12:08:00Z</published>
    <updated>2010-02-04T12:08:00Z</updated>
    <author>
      <name>SF</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-739580098595224395.post-6493402041955332850</id>
  </entry>
  <entry>
    <title>CPAN.pm local setting tool for comman use rental server</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/yukikimoto/20100206/1265284254" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I create CPAN.pm local setting tool for comman use rental server.It was
successed in (FreeBSD, csh)and (Fedora7, bash). sh,bash,ksh,zsh,csh,tcsh
is probably OK.

The way to setup CPAN.pm in comman use rental server

以下が手順になります。

# 1.Tool downloadperl -MLWP::Simple -e "getprint('http://github.com/yuki-kimoto/cpan-local-setup/raw/master/cpan_local_setup.pl')" &gt; cpan_local_setup.pl
# 2.Execute toolperl cpan_local_setup.pl
# 3. Reflect to a shell setting fileExecute the desplayed command(source setting_file)

If you know more simple and better way, please tell me that. It is best
that newbie can execute it in easy way.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>　I create CPAN.pm local setting tool for comman use rental server.It was successed in (FreeBSD, csh)and (Fedora7, bash). sh,bash,ksh,zsh,csh,tcsh is probably OK.</p>
			<h4>The way to setup CPAN.pm in comman use rental server</h4>
			<p>　以下が手順になります。</p>
<pre class="syntax-highlight">
<span class="synComment"># 1.Tool download</span>
perl -MLWP::Simple <span class="synStatement">-e</span> <span class="synConstant">"getprint('http://github.com/yuki-kimoto/cpan-local-setup/raw/master/cpan_local_setup.pl')"</span> &gt; cpan_local_setup.pl

<span class="synComment"># 2.Execute tool</span>
perl cpan_local_setup.pl

<span class="synComment"># 3. Reflect to a shell setting file</span>
Execute the desplayed command(source setting_file)
</pre>

			<p> </p>
			<p>If you know more simple and better way, please tell me that. It is best that newbie can execute it in easy way.</p>
		</div>
</div>
    </content>
    <published>2010-02-04T20:50:54+09:00</published>
    <updated>2010-02-04T20:50:54+09:00</updated>
    <author>
      <name>yukikimoto</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/yukikimoto/20100206/1265284254</id>
  </entry>
  <entry>
    <title>Do Passwords Right</title>
    <link rel="alternate" href="http://blog.afoolishmanifesto.com/archives/1286" type="text/html"/>
    <summary type="text">You all know not to put your passwords into the database in plaintext.
Catalyst and DBIx::Class::EncodedColumn make doing this super easy and
completely secure.

First off, you might want to check out the wikipedia article about
cryptographic hash functions. The gist of it though is this: a password
stored in plain text is obviously compromised if the passwords file gets
into the hands of evildoers. You can “hash” the passwords and they are
now harder for the attackers to transform into plain-text. If your
password is good it is nearly impossible, but basically what can happen
is that the attacker uses the algorithm to generate hashes for every word
in the dictionary or whatever and now they basically can crack all the
basic passwords.

You can take it a step further and “salt” your passwords (wikipedia salt
article.) A simple way of doing that is just to concatenate some string
onto the end of all of your passwords. This will make dictionary attempts
useless unless they know your salt. Typically when using a salt the salt
is kept secret.

And then you can have a unique salt per password. Imagine a scheme where
the salt is $username$id. It would require the attackers to basically
generate a dictionary per user!

The scheme we’ve settled on uses Eksblowfish. The DBIC Component for it
actually uses a 16 character randomly generated salt for every password.
Nice!

Ok, so how does one apply such sweet, sweet code? First, (always) set up
your model. This is a slightly trimmed version of ours:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

package MTSI::Schema::Result::User;

use strict;
use warnings;

use parent 'DBIx::Class::Core';

use CLASS;

CLASS-&gt;load_components(qw/EncodedColumn/);

CLASS-&gt;table('users');

CLASS-&gt;add_columns(
id =&gt; {
data_type =&gt; 'integer',
is_numeric =&gt; 1,
is_nullable =&gt; 0,
is_auto_increment =&gt; 1,
},
username =&gt; {
data_type =&gt; 'varchar',
size =&gt; 50,
is_nullable =&gt; 0,
},
password =&gt; {
data_type =&gt; 'CHAR',
size =&gt; 59,
encode_column =&gt; 1,
encode_class =&gt; 'Crypt::Eksblowfish::Bcrypt',
encode_args =&gt; { key_nul =&gt; 0, cost =&gt; 8 },
encode_check_method =&gt; 'check_password',
});

CLASS-&gt;set_primary_key('id');

1;

Easy peasy! The encode_check_method option for password basically puts a
method in your result class that you can call with a plaintext password
and it returns true or false if the password is legitimate. The nice
thing about that is that if you decide to switch to some other kind of
hashing, your controller stays the same. Model code for the win!

Next up, the Catalyst configuration. This was what took me a while to
find, but thanks to mst I finally found it yesterday. The package we use
for auth is the same one everyone uses in Cat:
Catalyst::Plugin::Authentication. The docs that I was looking for
specifically were the ones for
Catalyst::Authentication::Credential::Password. So after reading those
docs, the following is the catalyst config snippet one would use for
these nice passwords:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

'Plugin::Authentication' =&gt; {
use_session =&gt; 1,
default =&gt; {
credential =&gt; {
class =&gt; 'Password',
password_type =&gt; 'self_check',
},
store =&gt; {
class =&gt; 'DBIx::Class',
user_model =&gt; 'DB::User', #&lt;-- DB refers to the name of the
role_relation =&gt; 'roles', # model class we are using
use_userdata_from_session =&gt; 1,
}
}
},

Note: the password_type of self_check is what tells the controller to
just call $result-&gt;check_password($plaintext).

So there you have it. That’s all the code you need for secure passwords
with Catalyst. If you make a new project and your users passwords get
compromised it is your fault.

Have a nice day :-)


Related Posts:
--------------

  * OpenID with Catalyst and more

  * PerlMonks Getting Hacked and My Solution

  * New stuff in DBIx::Class::Helpers 2.00200

  * Latest additions to DBIC::Helpers

  * Paranoid Deletion in DBIx::Class

  * Powered by Contextual Related Posts</summary>
    <content type="html">&lt;p&gt;You all know not to put your passwords into the database in plaintext.  &lt;a href="http://search.cpan.org/perldoc?Catalyst::Runtime"&gt;Catalyst&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?DBIx::Class::EncodedColumn"&gt;DBIx::Class::EncodedColumn&lt;/a&gt; make doing this super easy and completely secure.&lt;/p&gt;
&lt;p&gt;First off, you might want to check out the &lt;a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function"&gt;wikipedia article&lt;/a&gt; about cryptographic hash functions.  The gist of it though is this: a password stored in plain text is obviously compromised if the passwords file gets into the hands of evildoers.  You can &amp;#8220;hash&amp;#8221; the passwords and they are now harder for the attackers to transform into plain-text.  If your password is good it is nearly impossible, but basically what can happen is that the attacker uses the algorithm to generate hashes for every word in the dictionary or whatever and now they basically can crack all the basic passwords.  &lt;/p&gt;
&lt;p&gt;You can take it a step further and &amp;#8220;salt&amp;#8221; your passwords (&lt;a href"http://en.wikipedia.org/wiki/salt_%28cryptography%29"&gt;wikipedia salt article&lt;/a&gt;.)  A simple way of doing that is just to concatenate some string onto the end of all of your passwords.  This will make dictionary attempts useless unless they know your salt.  Typically when using a salt the salt is kept secret.&lt;/p&gt;
&lt;p&gt;And then you can have a unique salt per password.  Imagine a scheme where the salt is $username$id.  It would require the attackers to basically generate a dictionary per user!&lt;/p&gt;
&lt;p&gt;The scheme we&amp;#8217;ve settled on uses &lt;a href="http://en.wikipedia.org/wiki/Crypt_(Unix)#Blowfish-based_scheme"&gt;Eksblowfish&lt;/a&gt;.  The &lt;a href="http://search.cpan.org/~frew/DBIx-Class-EncodedColumn-0.00006/lib/DBIx/Class/EncodedColumn/Crypt/Eksblowfish/Bcrypt.pm"&gt;DBIC Component&lt;/a&gt; for it actually uses a 16 character randomly generated salt for every password.  Nice!&lt;/p&gt;
&lt;p&gt;Ok, so how does one apply such sweet, sweet code?  First, (always) set up your model.  This is a slightly trimmed version of ours:&lt;/p&gt;
&lt;div class="codecolorer-container perl vibrant"&gt;&lt;table cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;br /&gt;33&lt;br /&gt;34&lt;br /&gt;35&lt;br /&gt;36&lt;br /&gt;37&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class="perl codecolorer"&gt;&lt;a href="http://perldoc.perl.org/functions/package.html"&gt;&lt;span&gt;package&lt;/span&gt;&lt;/a&gt; MTSI&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Schema&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;Result&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;use&lt;/span&gt; strict&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;use&lt;/span&gt; warnings&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;use&lt;/span&gt; parent &lt;span&gt;'DBIx::Class::Core'&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;use&lt;/span&gt; CLASS&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
CLASS&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;load_components&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;qw/EncodedColumn/&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
CLASS&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;table&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'users'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
CLASS&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;add_columns&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;id &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; data_type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'integer'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; is_numeric &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; is_nullable &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; is_auto_increment &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;username &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; data_type &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'varchar'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; size &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; is_nullable &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;password &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; data_type &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'CHAR'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; size &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;59&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; encode_column &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; encode_class &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'Crypt::Eksblowfish::Bcrypt'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; encode_args &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt; key_nul &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; cost &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;8&lt;/span&gt; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; encode_check_method &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'check_password'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
CLASS&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;set_primary_key&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'id'&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Easy peasy!  The encode_check_method option for password basically puts a method in your result class that you can call with a plaintext password and it returns true or false if the password is legitimate.  The nice thing about that is that if you decide to switch to some other kind of hashing, your controller stays the same.  Model code for the win!&lt;/p&gt;
&lt;p&gt;Next up, the Catalyst configuration.  This was what took me a while to find, but thanks to &lt;a href="http://www.shadowcat.co.uk/blog/matt-s-trout/"&gt;mst&lt;/a&gt; I finally found it yesterday.  The package we use for auth is the same one everyone uses in Cat: &lt;a href="http://search.cpan.org/perldoc?Catalyst::Plugin::Authentication"&gt;Catalyst::Plugin::Authentication&lt;/a&gt;.  The docs that I was looking for specifically were the ones for &lt;a href="http://search.cpan.org/perldoc?Catalyst::Authentication::Credential::Password"&gt;Catalyst::Authentication::Credential::Password&lt;/a&gt;.  So after reading those docs, the following is the catalyst config snippet one would use for these nice passwords:&lt;/p&gt;
&lt;div class="codecolorer-container perl vibrant"&gt;&lt;table cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class="perl codecolorer"&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;'Plugin::Authentication'&lt;/span&gt; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; use_session &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; default &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;credential &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; class &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'Password'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; password_type &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'self_check'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;store &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; class &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'DBIx::Class'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; user_model &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'DB::User'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;#&amp;lt;-- DB refers to the name of the &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; role_relation &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;'roles'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;# &amp;nbsp; &amp;nbsp; model class we are using&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; use_userdata_from_session &lt;span&gt;=&amp;gt;&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;#125;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Note: the password_type of self_check is what tells the controller to just call $result-&amp;gt;check_password($plaintext).&lt;/p&gt;
&lt;p&gt;So there you have it.  That&amp;#8217;s &lt;strong&gt;all the code&lt;/strong&gt; you need for secure passwords with Catalyst.  If you make a new project and your users passwords get compromised it is &lt;strong&gt;your fault&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Have a nice day &lt;img src="http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif" alt=":-)"&gt; &lt;/p&gt;
&lt;div id="crp_related"&gt;&lt;h2&gt;Related Posts:&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/913" rel="bookmark" class="crp_title"&gt;OpenID with Catalyst and more&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1028" rel="bookmark" class="crp_title"&gt;PerlMonks Getting Hacked and My Solution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1289" rel="bookmark" class="crp_title"&gt;New stuff in DBIx::Class::Helpers 2.00200&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/1261" rel="bookmark" class="crp_title"&gt;Latest additions to DBIC::Helpers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.afoolishmanifesto.com/archives/274" rel="bookmark" class="crp_title"&gt;Paranoid Deletion in DBIx::Class&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Powered by &lt;a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/"&gt;Contextual Related Posts&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</content>
    <category term="Uncategorized catalyst dbix::class dbix::class::encodedcolumn eksblowfish perl"/>
    <published>2010-02-04T05:20:47Z</published>
    <updated>2010-02-04T05:20:47Z</updated>
    <author>
      <name>fREW Schmidt</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://blog.afoolishmanifesto.com/?p=1286</id>
  </entry>
  <entry>
    <title>App::Options</title>
    <link rel="alternate" href="http://id-perl.blogspot.com/2010/02/appoptions.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Over the course of many years, I have written lots of lots of short
command-line scripts in Perl (Perl's great for that, you know). Most of
these scripts are small utilities, or replacement for shell scripts, or
automation tools.

All of these scripts invariably need some ability to take command-line
options. Of course, back in the days, I used Getopt::Std and
Getopt::Long. They both did their task well, but also invariably I will
need to provide -h or --help for usage information. I always hate having
to write this usage text manually.

Also, if you use your scripts often enough, you will end up with the same
incantation for some, that you will want to put the command line options
to a config file to avoid repeating yourself. Passwords are also not
appropriate in command-line options due to security issues.

So I now use App::Options and have never looked back. You can look at it
as a pretty straightforward replacement for Getopt::Long, but it gives
you automatic --help and --version (--program_version actually, but
--version also does something else wonderful). And it automatically
enables you to read config files. I emphasize "automatically" because you
absolutely do not have to do a single thing, as App::Options gives you
some nice defaults on where to find the config files.

How great is that? Just write your code as if you're using Getopt::Long,
but gain all these extra abilities for free!

There are other solutions for command-line scripts, like App::Cmd, but
really App::Options is the easiest way especially for old-timers like me
who do not want to change their Getopt::Long-style habit.

App::Options is not perfect though. There are a couple of small
annoyances I have about it, but I'm not hung up on them. The first is
that "=" in command-line option is required, i.e. you have to write
"--opt=args" instead of "--opt args". Second is, --version defaults to
displaying Perl modules version instead of your program's version.

For larger apps, I also sometimes need hierarchical/multilevel
configuration. It'd also be nice to have YAML support. These are
something I hope to accomplish with Config::Tree, but I guess I still
need to work on it quite a bit before I can replace my usage of
App::Options with it.</div>
    </summary>
    <content type="text">Over the course of many years, I have written lots of lots of short command-line scripts in Perl (Perl's great for that, you know). Most of these scripts are small utilities, or replacement for shell scripts, or automation tools.&lt;br /&gt;&lt;br /&gt;All of these scripts invariably need some ability to take command-line options. Of course, back in the days, I used Getopt::Std and Getopt::Long. They both did their task well, but also invariably I will need to provide -h or --help for usage information. I always hate having to write this usage text manually.&lt;br /&gt;&lt;br /&gt;Also, if you use your scripts often enough, you will end up with the same incantation for some, that you will want to put the command line options to a config file to avoid repeating yourself. Passwords are also not appropriate in command-line options due to security issues.&lt;br /&gt;&lt;br /&gt;So I now use &lt;a href="http://search.cpan.org/dist/App-Options/"&gt;App::Options&lt;/a&gt; and have never looked back. You can look at it as a pretty straightforward replacement for Getopt::Long, but it gives you automatic --help and --version (--program_version actually, but --version also does something else wonderful). And it &lt;b&gt;automatically&lt;/b&gt; enables you to read config files. I emphasize "automatically" because you absolutely do not have to do a single thing, as App::Options gives you some nice defaults on where to find the config files.&lt;br /&gt;&lt;br /&gt;How great is that? Just write your code as if you're using Getopt::Long, but gain all these extra abilities for free!&lt;br /&gt;&lt;br /&gt;There are other solutions for command-line scripts, like &lt;a href="http://search.cpan.org/dist/App-Cmd/"&gt;App::Cmd&lt;/a&gt;, but really App::Options is the easiest way especially for old-timers like me who do not want to change their Getopt::Long-style habit.&lt;br /&gt;&lt;br /&gt;App::Options is not perfect though. There are a couple of small annoyances I have about it, but I'm not hung up on them. The first is that "=" in command-line option is required, i.e. you have to write "--opt=args" instead of "--opt args". Second is, --version defaults to displaying Perl modules version instead of your program's version.&lt;br /&gt;&lt;br /&gt;For larger apps, I also sometimes need hierarchical/multilevel configuration. It'd also be nice to have YAML support. These are something I hope to accomplish with &lt;a href="http://search.cpan.org/dist/Config-Tree/"&gt;Config::Tree&lt;/a&gt;, but I guess I still need to work on it quite a bit before I can replace my usage of App::Options with it.&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="steven cpan perl"/>
    <published>2010-02-04T00:07:00Z</published>
    <updated>2010-02-04T00:07:00Z</updated>
    <author>
      <name>Steven Haryanto</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-3035323255246508397.post-7865629953843285091</id>
  </entry>
  <entry>
    <title>Spooky</title>
    <link rel="alternate" href="http://howcaniexplainthis.blogspot.com/2010/02/spooky.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">This is just a small anecdote.

Tonight, I finished a small Perl 5 script that I've been wanting to
complete for a while, but where I was a bit nervous that I'd fsck it up
right and good.

It was a script designed to handle two tab-separated text sources; one a
list of tournament IDs and tournament names, the other a list of player
results, one line per result with the player ID, tournament name,
position and score achieved.

I achieved this by creating a hash of hashes for each file, referencing
the first while parsing the other, and bravely inserting the data into a
single database table.

I tested my code piece for piece while building it, which is sensible in
itself, but what spooked me was this:

There was not a single bug. The script did what it was supposed to do,
all along.

That's not supposed to happen.

I need a drink.</div>
    </summary>
    <content type="text">This is just a small anecdote.&lt;br /&gt;&lt;br /&gt;Tonight, I finished a small Perl 5 script that I've been wanting to complete for a while, but where I was a bit nervous that I'd fsck it up right and good.&lt;br /&gt;&lt;br /&gt;It was a script designed to handle two tab-separated text sources; one a list of tournament IDs and tournament names, the other a list of player results, one line per result with the player ID, tournament &lt;em&gt;name&lt;/em&gt;, position and score achieved.&lt;br /&gt;&lt;br /&gt;I achieved this by creating a hash of hashes for each file, referencing the first while parsing the other, and &lt;em&gt;bravely inserting the data into a single database table&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;I tested my code piece for piece while building it, which is sensible in itself, but what spooked me was this:&lt;br /&gt;&lt;br /&gt;There was not a single bug.  The script did what it was supposed to do, all along.&lt;br /&gt;&lt;br /&gt;That's not supposed to happen.&lt;br /&gt;&lt;br /&gt;I need a drink.&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="Perl Perl 5"/>
    <published>2010-02-03T23:21:00Z</published>
    <updated>2010-02-03T23:21:00Z</updated>
    <author>
      <name>bakkushan</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-753668960778118906.post-9058131186463084664</id>
  </entry>
  <entry>
    <title>DBD::ODBC and date/time/datetime/timestamp</title>
    <link rel="alternate" href="http://www.martin-evans.me.uk/node/54" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Over the last few months I've been receiving an increasing number of
emails from people experiencing problems inserting
date/time/datetime/timestamp values into MS SQL Server specifically
although not exclusively. There are a number of MS SQL Server ODBC
drivers but the ones I see the most (in no particular order) are a) MS
SQL Server ODBC Driver b) MS SQL Server Native Client driver c)
Easysoft's SQL Server ODBC Driver and d) freeTDS.

I hope to write a more expansive tutorial on this in the near future but
until then I hope this blog post will help.

read more</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>Over the last few months I've been receiving an increasing number of emails from people experiencing problems inserting date/time/datetime/timestamp values into MS SQL Server specifically although not exclusively. There are a number of MS SQL Server ODBC drivers but the ones I see the most (in no particular order) are a) MS SQL Server ODBC Driver b) MS SQL Server Native Client driver c) Easysoft's SQL Server ODBC Driver and d) freeTDS.</p>
<p>I hope to write a more expansive tutorial on this in the near future but until then I hope this blog post will help.</p>
<p><a href="http://www.martin-evans.me.uk/node/54" target="_blank">read more</a></p></div>
    </content>
    <category term="DBD::ODBC Perl"/>
    <published>0</published>
    <updated>0</updated>
    <author>
      <name>martinjevans</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:54 at http://www.martin-evans.me.uk</id>
  </entry>
  <entry>
    <title>Project Stepping Stones</title>
    <link rel="alternate" href="http://bricas.vox.com/library/post/project-stepping-stones.html?_c=feed-atom" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"> Ever looked back at something you've worked on and thought: "Gee, it's
too bad that project didn't get to it's ultimate goal, but, I've learned
a lot from it." I have one of those projects. Such is the world of
technology, your toolset is constant...

Read and post comments | Send to a friend</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            
                <div xmlns:at="http://www.sixapart.com/ns/at">
         Ever looked back at something you've worked on and thought: "Gee, it's too bad that project didn't get to it's ultimate goal, but, I've learned a lot from it." I have one of those projects. Such is the world of technology, your toolset is constant...   <p> 
    <a href="http://bricas.vox.com/library/post/project-stepping-stones.html?_c=feed-atom#comments">Read and post comments</a>   |   
    <a href="http://www.vox.com/share/6a00d09e62f541be2b0123dde1d96c860b?_c=feed-atom">Send to a friend</a> 
</p>

                </div>
            
        </div>
    </content>
    <category term="perl lucene-ws solr"/>
    <published>2010-02-03T20:35:02Z</published>
    <updated>2010-02-03T20:35:02Z</updated>
    <author>
      <name>Brian</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:vox.com,2010-02-03:asset-6a00d09e62f541be2b0123dde1d96c860b</id>
  </entry>
  <entry>
    <title>Geo::Ellipsoid</title>
    <link rel="alternate" href="http://onperl.ru/onperl/2010/02/geoellipsoid.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Из записной книжки программиста.

Январь

Я, конечно, знал, что Земля не идеальный шар, что он как-то приплюснут и
называется то ли эллипсоидом, то ли геоидом, то ли еще как-то. Из
университетских лекций в памяти держится название сферы вращения, ну да,
ну и что дальше-то. Надо было посчитать расстояние между двумя точками на
Земле, и пытаться восстановить в памяти весь курс трехмерной геометрии,
да еще сделать поправки на неидеальность шара, — задача, конечно,
интересная, но такой подход был бы совсем непрактичным. Хочется же и
получить быстро результат, и порадоваться, и закрыть задачу.

Когда Яндекс открывал свои «Самолетики», они ввернули в заметке в их
корпоративном блоге какое-то умное слово — ортодромии. Ну явно для того,
чтобы поумничать. Кто же не знает, что ортодромия — это не про нашу
Землю, это лишь кратчайший путь на поверхности сферы вращения. Мне-то
нужно найти конкретный модуль по употребимому английскому названию и
именно для Земли. Это название — great circle. Ищем.

На спане быстро нашлась пара модулей, про один из которых в первой же
строке документации написано, что он broken, а второй вроде ничего. Разве
что название космической длины. Не страшно, берем в дело, радуемся и
закрываем задачу.

Февраль

Стало скучно, что мы тут уже месяц считаем расстояние по ровненькому
шару, а Украина до сих пор не выбрала президента. Что же там есть на
спане еще? Йоу! Есть модуль Geo::Ellipsoid, и в нем с десяток разных
формул, по которым описывают форму Земли. Хочу.

Так, что нужно? Интерфейс странноват, но понятен. Попробую на старом
примере, посчитаю расстояние от Москвы до Киева. Как хорошо, что в папке
/test у меня все это сохранилось, не надо заново искать координаты.

use v5.10;
use strict;
use Geo::Ellipsoid;

my @moscow = (55.7522, 37.6156);
my @kiev = (50.4333, 30.5167);

my $geo = new Geo::Ellipsoid(
ellipsoid =&gt; 'WGS84',
units =&gt; 'degrees',
distance_units =&gt; 'kilometers'
);

my $dist = $geo-&gt;range(
$moscow[0], $moscow[1], $kiev[0], $kiev[1]
);
say $dist;

В очередной раз напрягся, восстанавливая в памяти, что из longitude и
latitude широта, а что — долгота, но вроде не перепутал и получил ответ,
поохожий на правду. С GIS::Distance было 757 километров, с Geo::Ellipsoid
— 759. (А оно должно было стать больше или меньше? Хотя какая разница,
если все равно города на разной высоте относительно моря.)

Закоммичу, пожалуй.

Три минуты спустя

Коллега, прочитавший пришедший в почту дифф коммита, пишет: «Хм, а
GIS:Distance::Formula::GeoEllipsoid?». Что это? Позырю. Блядь, я же
забыл, что GIS::Distance может еще считать и по эллипсоиду. Читал же,
когда его пробовал в прошлый раз. GIS::Distance это обертка, которая
делегирует все расчеты другим модулям. Вместо того, чтобы приделывать
новый модуль, можно было бы просто указать параметр ellipsoid =&gt; 'WGS84'
к существующему. Незадача какая, сраный спан без аннотированных
перекрестных ссылок.</div>
    </summary>
    <content type="html">
        &lt;p&gt;Из записной книжки программиста.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Январь&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Я, конечно, знал, что Земля не идеальный шар, что он как-то приплюснут и называется то ли эллипсоидом, то ли геоидом, то ли еще как-то. Из университетских лекций в памяти держится название сферы вращения, ну да, ну и что дальше-то.&amp;nbsp;Надо было посчитать расстояние между двумя точками на Земле, и пытаться восстановить в памяти весь курс трехмерной геометрии, да еще сделать поправки на неидеальность шара, — задача, конечно, интересная, но такой подход был бы совсем непрактичным. Хочется же и получить быстро результат, и порадоваться,&amp;nbsp;и закрыть задачу.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Когда Яндекс открывал свои «Самолетики», они ввернули в заметке в их корпоративном&amp;nbsp;блоге какое-то умное слово — ортодромии. Ну явно для того, чтобы поумничать. Кто же не знает, что ортодромия — это не про нашу Землю, это лишь кратчайший путь на поверхности сферы вращения. Мне-то нужно найти конкретный модуль по употребимому английскому названию и именно для Земли. Это название — great circle. Ищем. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;На спане быстро нашлась &lt;a href="http://search.cpan.org/search?query=greatcircle&amp;amp;mode=all"&gt;пара модулей&lt;/a&gt;, про один из которых в первой же строке документации написано, что он broken, а второй вроде ничего. Разве что название космической длины. Не страшно, &lt;a href="http://onperl.ru/onperl/2010/01/geogoogleearthpluggableplugingreatcircle.html"&gt;берем в дело&lt;/a&gt;, радуемся и закрываем задачу.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Февраль&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Стало скучно, что мы тут уже месяц считаем расстояние по ровненькому шару, а Украина до сих пор не выбрала президента. Что же там есть на спане еще? Йоу! Есть модуль &lt;a href="http://search.cpan.org/perldoc?Geo::Ellipsoid"&gt;Geo::Ellipsoid&lt;/a&gt;, и в нем с десяток разных формул, по которым описывают форму Земли. Хочу.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Так, что нужно? Интерфейс странноват, но понятен. Попробую на старом примере, посчитаю расстояние от Москвы до Киева. Как хорошо, что в папке&amp;nbsp;/test у меня все это сохранилось, не надо заново искать координаты.&lt;/em&gt;&lt;/p&gt;&lt;tt&gt;
&lt;p&gt;&lt;em&gt;use v5.10;&lt;br /&gt;use strict;&lt;br /&gt;use Geo::Ellipsoid;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;my @moscow = (55.7522, 37.6156);&lt;br /&gt;my @kiev = (50.4333, 30.5167);&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;my $geo = new Geo::Ellipsoid(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ellipsoid =&amp;gt; 'WGS84',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; units =&amp;gt; 'degrees',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; distance_units =&amp;gt; 'kilometers'&lt;br /&gt;);&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;my $dist = $geo-&amp;gt;range(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $moscow[0], $moscow[1], $kiev[0], $kiev[1]&lt;br /&gt;);&lt;br /&gt;say $dist;&lt;/em&gt;&lt;/p&gt;&lt;/tt&gt;
&lt;p&gt;&lt;em&gt;В очередной раз напрягся, восстанавливая в памяти, что из longitude и latitude широта, а что — долгота, но вроде не&amp;nbsp;перепутал и получил ответ, поохожий на правду. С GIS::Distance было 757 километров, с Geo::Ellipsoid — 759. (А оно должно было стать больше или меньше? Хотя какая разница, если все равно города на разной высоте относительно моря.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Закоммичу, пожалуй.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Три минуты спустя&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Коллега, прочитавший пришедший в почту дифф коммита, пишет: «Хм, а GIS:D&lt;/img&gt;istance::Formula::GeoEllipsoid?». Что это? Позырю. Блядь, я же забыл, что GIS::Distance может еще считать и по эллипсоиду. Читал же, когда его пробовал в прошлый раз. GIS::Distance это обертка, которая делегирует все расчеты другим модулям. Вместо того, чтобы&amp;nbsp;приделывать новый модуль, можно было бы просто&amp;nbsp;указать параметр ellipsoid =&amp;gt; 'WGS84'&amp;nbsp;к существующему.&amp;nbsp;Незадача какая, сраный спан без аннотированных перекрестных ссылок.&lt;/p&gt;&lt;/em&gt;
        
    </content>
    <category term="Приложения geo geo::ellipsoid perl"/>
    <published>2010-02-03T21:29:35+01:00</published>
    <updated>2010-02-03T21:29:35+01:00</updated>
    <author>
      <name>ash</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:onperl.ru,2010:/onperl//1.129</id>
  </entry>
  <entry>
    <title>Binary Tree</title>
    <link rel="alternate" href="http://lastofthecarelessmen.blogspot.com/2010/02/binary-tree.html" type="text/html"/>
    <summary type="text">So, while reading over #perl6 today, I noticed comments about how
out-of-date Exegesis 2's first example was. Even the updates to it are
out of date! I thought it would be fun and simple to update it to working
modern Perl 6, as embodied in Rakudo master. (As ng has still not
landed.)

Well, it seemed like a good idea when I started. However, I've run into
an odd issue. Here's my simplified which doesn't work:

# bintree - binary tree demo program 
# adapted from "Perl Cookbook", Recipe 11.15
# converted to modern Perl 6 by SF
use v6;

my (%root, $n);
for (1..1000).pick(2) {
    say "Inserting $_";
    insert(%root, $_);
    say %root.perl;
}

say %root.keys;
say "Doom";

#########################################
sub insert(Hash $tree is rw, Int $val) {
    unless $tree {
        my %node;
        %node&lt;LEFT&gt;   = Hash;
        %node&lt;RIGHT&gt;  = Hash;
        %node&lt;VALUE&gt;  = $val ; # but Found(0);
        say %node.perl;
        $tree = %node;
        say $tree.perl;
        return;
    }
    if    ($tree&lt;VALUE&gt; &gt; $val) { insert($tree&lt;LEFT&gt;,  $val) }
    elsif ($tree&lt;VALUE&gt; &lt; $val) { insert($tree&lt;RIGHT&gt;, $val) }
    else                        { warn "dup insert of $val\n" }
}



And here's sample output:


Inserting 640
{"VALUE" =&gt; 640, "RIGHT" =&gt; Hash, "LEFT" =&gt; Hash}
{"VALUE" =&gt; 640, "RIGHT" =&gt; Hash, "LEFT" =&gt; Hash}
{}
Inserting 461
{"VALUE" =&gt; 461, "RIGHT" =&gt; Hash, "LEFT" =&gt; Hash}
{"VALUE" =&gt; 461, "RIGHT" =&gt; Hash, "LEFT" =&gt; Hash}
{}


If you match that back up with the says in the code, you'll see that a
value is assigned to $tree in insert, but that value does not make it
back to the point where insert is called, despite $tree is rw. I've no
idea why this should be the case, the same sort of code seems to work
quite well in the REPL. Does anyone have an idea? Am I doing something
stupid here, or did I just find a bug in a very-soon-to-be-obsolete
version of Rakudo?

Update: Not sure if this is just something I don't understand or a
rakudobug. It turns out that the problem is the line $tree = %node. If I
use equals to assign something to $tree, that doesn't get passed back
out. On the other hand, if I add hash keys directly to $tree, they are
passed out just like I would expect.</summary>
    <content type="text">So, while reading over #perl6 today, I noticed comments about how out-of-date &lt;a href="http://dev.perl.org/perl6/doc/design/exe/E02.html"&gt;Exegesis 2's first example&lt;/a&gt; was.  Even the updates to it are out of date!  I thought it would be fun and simple to update it to working modern Perl 6, as embodied in Rakudo master.  (As ng has still not landed.)&lt;br /&gt;&lt;br /&gt;Well, it seemed like a good idea when I started.  However, I've run into an odd issue.  Here's my simplified which doesn't work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span&gt;# bintree - binary tree demo program &lt;/span&gt;&lt;br /&gt;&lt;span&gt;# adapted from &amp;quot;Perl Cookbook&amp;quot;, Recipe 11.15&lt;/span&gt;&lt;br /&gt;&lt;span&gt;# converted to modern Perl 6 by SF&lt;/span&gt;&lt;br /&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;v&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;my&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pick&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;Inserting &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;_&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;perl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;;&lt;br /&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;Doom&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;#########################################&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Hash&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rw&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;unless&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;my&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Hash&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Hash&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# but Found(0);&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;perl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;say&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;perl&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;elsif&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VALUE&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;insert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;tree&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;RIGHT&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;dup insert of &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;val&lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And here's sample output:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;Inserting 640&lt;br /&gt;{"VALUE" =&amp;gt; 640, "RIGHT" =&amp;gt; Hash, "LEFT" =&amp;gt; Hash}&lt;br /&gt;{"VALUE" =&amp;gt; 640, "RIGHT" =&amp;gt; Hash, "LEFT" =&amp;gt; Hash}&lt;br /&gt;{}&lt;br /&gt;Inserting 461&lt;br /&gt;{"VALUE" =&amp;gt; 461, "RIGHT" =&amp;gt; Hash, "LEFT" =&amp;gt; Hash}&lt;br /&gt;{"VALUE" =&amp;gt; 461, "RIGHT" =&amp;gt; Hash, "LEFT" =&amp;gt; Hash}&lt;br /&gt;{}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;If you match that back up with the says in the code, you'll see that a value is assigned to &lt;code&gt;$tree&lt;/code&gt; in &lt;code&gt;insert&lt;/code&gt;, but that value does not make it back to the point where &lt;code&gt;insert&lt;/code&gt; is called, despite &lt;code&gt;$tree is rw&lt;/code&gt;.  I've no idea why this should be the case, the same sort of code seems to work quite well in the REPL.  Does anyone have an idea?  Am I doing something stupid here, or did I just find a bug in a very-soon-to-be-obsolete version of Rakudo?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; Not sure if this is just something I don't understand or a rakudobug.  It turns out that the problem is the line &lt;code&gt;$tree = %node&lt;/code&gt;.  If I use equals to assign something to &lt;code&gt;$tree&lt;/code&gt;, that doesn't get passed back out.  On the other hand, if I add hash keys directly to &lt;code&gt;$tree&lt;/code&gt;, they are passed out just like I would expect.&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="Perl 6"/>
    <published>2010-02-03T19:33:00Z</published>
    <updated>2010-02-03T19:33:00Z</updated>
    <author>
      <name>SF</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-739580098595224395.post-6207086736664655148</id>
  </entry>
  <entry>
    <title>Perl for Windows statistics</title>
    <link rel="alternate" href="http://szabgab.com/blog/2010/02/1265247260.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Adam Kennedy pointed me to the download count of Strawberry Perl for
Windows. this shows that in the last 3 months there were approximately
54K downloads of 5.10.x and 4.5K downloads of 5.8.x That would be about
650 downloads a day.

Back on 7/7/2007 Jan Dubois mentioned that ActiveState has more than
4,500 downloads of ActivePerl 5.8.x per day for Windows and more than
1,000 downloads of ActivePerl 5.6.1 per day.

Unfortunatelly I don't have newer numbers from ActiveState but it would
be interesting to see how have the numbers changed? Also it would be nice
if we had numbers from the other Perl distributions for Windows.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>
<a href="http://ali.as/">Adam Kennedy</a> pointed me to the 
<a href="http://code.google.com/p/strawberry-perl/downloads/list?can=1&amp;q=&amp;sort=uploaded&amp;colspec=Filename%20Summary%20Uploaded%20Size%20DownloadCount">download count of Strawberry Perl for Windows</a>.
this shows that in the last 3 months there were approximately 54K downloads of 5.10.x and 4.5K downloads of 5.8.x That would be about 650 downloads a day.
</p>
<p>
Back on 7/7/2007 Jan Dubois <a href="http://aspn.activestate.com/ASPN/Mail/Message/perl5-porters/3521207">mentioned</a>
that <a href="http://www.activestate.com/">ActiveState</a> has more than 4,500 downloads of ActivePerl 5.8.x per day for Windows
and more than 1,000 downloads of ActivePerl 5.6.1 per day.
</p>
<p>
Unfortunatelly I don't have newer numbers from ActiveState but it would be interesting to see how have the numbers 
changed? Also it would be nice if we had numbers from the other Perl distributions for Windows.
</p>
</div>
    </content>
    <category term="Perl, Windows, Activestate, Strawberry Perl"/>
    <published>2010-02-03T17:34:20Z</published>
    <updated>2010-02-03T17:34:20Z</updated>
    <author>
      <name>Gabor Szabo</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://szabgab.com/blog/2010/02/1265247260.html</id>
  </entry>
  <entry>
    <title>
    Perl Regular Expressions
  </title>
    <link rel="alternate" href="http://my.opera.com/EinSascha/blog/show.dml/7317801" type="text/html"/>
    <summary type="text">Beginnend mit Heute, stelle ich die meiner Meinung nach wichtigsten
Fähigkeiten von Perl vor. Regular Expressions (inklusive Suchen und
Ersetzen), Hashes, foreach-Schleifen und &lt;FILEHANDLE&gt;-Konstrukte.</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <strong>Beginnend mit Heute, stelle ich die meiner Meinung nach wichtigsten Fähigkeiten von Perl vor. Regular Expressions (inklusive Suchen und Ersetzen), Hashes, foreach-Schleifen und &lt;FILEHANDLE&gt;-Konstrukte.</strong>
      </div>
    </content>
    <published>2010-02-03T18:08:47+01:00</published>
    <updated>2010-02-03T18:08:47+01:00</updated>
    <author>
      <name>Sascha    </name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://my.opera.com/EinSascha/blog/7317801</id>
  </entry>
  <entry>
    <title>flymake for perl syntax checking on the fly in emacs</title>
    <link rel="alternate" href="http://marinp.blogs.uv.es/2010/02/03/flymake-for-perl-syntax-checking-on-the-fly-emacs/" type="text/html"/>
    <summary type="text">If you are tired of M-! perl -wc myscript for syntax checking, there
fancy minor mode: flymake for syntax checking on the fly while
programming in emacs

Here is a video how it works:
http://blog.marcelotoledo.org/2007/07/11/emacs-flymake/

and a warning from Merlin:

beware perl -c on unknown code

by merlyn (47) &lt;merlyn@stonehenge.com&gt; on 2006.11.07 22:43 (#51498)
( http://www.stonehenge.com/merlyn/ | Last Journal: 2007.09.21 11:04 )
All I have to do now is send you a perl script to “look at” that
contains:

  BEGIN { system 'rm -rf $HOME' }

and hope that you look at it in your editor. That flymake code will
nicely execute that system operation. Oops!
– 

  * Randal L. Schwartz

  * Stonehenge</summary>
    <content type="html">&lt;p&gt;If you are tired of &lt;strong&gt;M-! perl -wc myscript for&lt;/strong&gt; syntax checking, there fancy minor mode: &lt;a href="http://flymake.sourceforge.net/"&gt;&lt;strong&gt;flymake&lt;/strong&gt;&lt;/a&gt; for syntax checking on the fly while programming in emacs&lt;/p&gt;
&lt;p&gt;Here is a video how it works:&lt;br /&gt;
http://blog.marcelotoledo.org/2007/07/11/emacs-flymake/&lt;/p&gt;
&lt;p&gt;and a warning from Merlin:&lt;/p&gt;
&lt;div&gt;&lt;strong&gt;&lt;a name="51498"&gt;beware perl -c on unknown code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;by    &lt;a href="http://use.perl.org/%7Emerlyn/"&gt;merlyn (47)&lt;/a&gt; &lt;span&gt;&amp;lt;&lt;a href="mailto:merlyn%40stonehenge.com"&gt;merlyn@stonehenge.com&lt;/a&gt;&amp;gt;    on 2006.11.07 22:43     (&lt;a href="http://use.perl.org/comments.pl?sid=33573&amp;amp;op=&amp;amp;threshold=0&amp;amp;commentsort=0&amp;amp;mode=thread&amp;amp;cid=51498"&gt;#51498&lt;/a&gt;)&lt;br /&gt;
(       &lt;a href="http://www.stonehenge.com/merlyn/"&gt;http://www.stonehenge.com/merlyn/&lt;/a&gt; |                    Last Journal:       &lt;a href="http://use.perl.org/%7Emerlyn/journal/"&gt;2007.09.21 11:04&lt;/a&gt; ) &lt;/span&gt; All I have to do now is send you a perl script to &amp;#8220;look at&amp;#8221; that contains:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;BEGIN { system 'rm -rf $HOME' }&lt;/tt&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;and hope that you look at it in your editor.  That flymake code will nicely execute that system operation.  Oops!&lt;br /&gt;
&amp;#8211;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Randal L. Schwartz&lt;/li&gt;
&lt;li&gt;Stonehenge&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content>
    <category term="emacs perl"/>
    <published>2010-02-03T15:46:21+01:00</published>
    <updated>2010-02-03T15:46:21+01:00</updated>
    <author>
      <name>Pablo MARIN-GARCIA</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://marinp.blogs.uv.es/2010/02/03/86/</id>
  </entry>
  <entry>
    <title>The terrible things (2): More daisies for the chain</title>
    <link rel="alternate" href="http://mdk.per.ly/2010/02/03/the-terrible-things-2-more-daisies-for-the-chain/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">My, Apparent, Ironman Status
      My Ironman Status

This is the second article based upon my Keynote that I presented this
year and is part of a series of articles on the Terrible Things We All
Must Do.


Lead by example…
----------------

One of the points I made in my Daisy Chain article last week was the need
to link to each other in our blogs and social media locales. So I have
resolved myself to lead by example and to try and do that as much as I
can. To this end I will be attempting to blog to Ironman twice a week
from now on (when necessary) so that I can link to and discuss other
peoples blogs and the groovy things I read on them.

Basically I am gossiping.


Wrap it up and Design
---------------------

There was a great post by XSawyerX (http://blogs.perl.org/users/sawyer_x)
which pointed out the need for all Perl modules/libraries/projects to
have a good looking website. This went from a series of discussions he
had concerning popularity of projects being connected to how they present
themselves.

My feeling is that this is part of the problem, not the whole of the
issue (not that he implies that, I am just talking out my thoughts) and
that there are some other things for us to consider in the marketing and
understanding of the marketplace, some of which I am going to try and
cover in this series of posts.

But his idea to have a website for every project, that looks good and
promotes the item is a solid one and I join Leo Lapworth (http://blogs.perl.org/users/leo_lapworth)
in supporting him, check out his post on More Design Love.


Outside the Bubble
------------------

FOSDEM happens this week and the energetic Mister Szabo will be manning
the stand and presenting papers on Perl to a wider audience, so if anyone
can get there then please seek him and the other volunteers, including
the indomitable Master Dave Cross, and say hello. This is really a great
effort and it is good to note that they are also getting some help form
the wonderful TPF (The Perl Foundation Homepage) at this event.


Frameworks
----------

The other notable item for me this week was the article by Stevan Little
On Frameworks, I really like Stevan’s blog he always seems so wide read,
considering how busy the guy is I wonder how he makes the time to do so
much reading and thinking on things. Thankfully I can read his blog so
that I don’t have to think about them : ). Also good to note that
Miyagawa has taken yet another step closer to a version 1.0 release of
Plack (Plack the Perl Web Server)


Cultured Perlers
----------------

In a bold move I have decided that I will start yet another blog
initiative (I currently blog to 4 places, some more than others which are
all linked from flavors.me/mdk) if Dave Cross gets his Cultured Perl site
up and running. I like the idea and have expressed the need for more
introduction/promotion of the Perl community to a wider world and
expressed this as part of my keynote, so I felt obliged to join in. My
only concern will be the overlap with this blog and the strain on my
limited writing capabilities. But, hey ho, we will see what happens.
Hopefully Dave will let us all know soon what is going on.

That wraps up my week of Ironman posts that I needed to share with you.

-ttfn – Mark

ironsignup</div>
    </summary>
    <content type="html">&lt;div&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;img src="http://ironman.enlightenedperl.org/munger/mybadge/male/mdk.png" alt="My, Apparent, Ironman Status"&gt;&lt;/dt&gt;
&lt;dd&gt;My Ironman Status&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;This is the second article based upon my &lt;a href="http://blip.tv/file/3126029"&gt;Keynote&lt;/a&gt; that I presented this year and is part of a series of articles on the Terrible Things We All Must Do.&lt;/p&gt;
&lt;h2&gt;Lead by example&amp;#8230;&lt;/h2&gt;
&lt;p&gt;One of the points I made in my Daisy Chain article last week was the need to link to each other in our blogs and social media locales. So I have resolved myself to lead by example and to try and do that as much as I can. To this end I will be attempting to blog to Ironman twice a week from now on (when necessary) so that I can link to and discuss other peoples blogs and the groovy things I read on them.&lt;/p&gt;
&lt;p&gt;Basically I am gossiping.&lt;/p&gt;
&lt;h2&gt;Wrap it up and Design&lt;/h2&gt;
&lt;p&gt;There was a &lt;a href="http://blogs.perl.org/users/sawyer_x/2010/02/marketing-the-entire-box-including-the-wrapper.html"&gt;great post by XSawyerX&lt;/a&gt; (&lt;a href="http://blogs.perl.org/users/sawyer_x"&gt;http://blogs.perl.org/users/sawyer_x&lt;/a&gt;) which pointed out the need for all Perl modules/libraries/projects to have a good looking website. This went from a series of discussions he had concerning popularity of projects being connected to how they present themselves.&lt;/p&gt;
&lt;p&gt;My feeling is that this is part of the problem, not the whole of the issue (not that he implies that, I am just talking out my thoughts) and that there are some other things for us to consider in the marketing and understanding of the marketplace, some of which I am going to try and cover in this series of posts.&lt;/p&gt;
&lt;p&gt;But his idea to have a website for every project, that looks good and promotes the item is a solid one and I join &lt;a href="http://blogs.perl.org/users/leo_lapworth"&gt;Leo Lapworth&lt;/a&gt; (&lt;a href="http://blogs.perl.org/users/leo_lapworth"&gt;http://blogs.perl.org/users/leo_lapworth&lt;/a&gt;) in supporting him, check out his post on &lt;a href="http://blogs.perl.org/users/leo_lapworth/2010/02/more-design-love-please.html"&gt;More Design Love&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Outside the Bubble&lt;/h2&gt;
&lt;p&gt;FOSDEM happens this week and the energetic &lt;a href="http://szabgab.com/blog/2010/02/1265137032.html"&gt;Mister Szabo&lt;/a&gt; will be manning the stand and presenting papers on Perl to a wider audience, so if anyone can get there then please seek him and the other volunteers, including the indomitable &lt;a href="http://perlhacks.com/2010/02/fosdem.php"&gt;Master Dave Cross&lt;/a&gt;, and say hello. This is really a great effort and it is good to note that they are also getting some help form the wonderful &lt;a href="http://www.perlfoundation.org/"&gt;TPF&lt;/a&gt; (&lt;a href="http://www.perlfoundation.org/"&gt;The Perl Foundation Homepage&lt;/a&gt;) at this event.&lt;/p&gt;
&lt;h2&gt;Frameworks&lt;/h2&gt;
&lt;p&gt;The other notable item for me this week was the article by &lt;a href="http://stevan-little.blogspot.com/"&gt;Stevan Little&lt;/a&gt; &lt;a href="http://stevan-little.blogspot.com/2010/02/on-frameworks.html"&gt;On Frameworks&lt;/a&gt;, I really like &lt;a href="http://stevan-little.blogspot.com/"&gt;Stevan&amp;#8217;s blog&lt;/a&gt; he always seems so wide read, considering how busy the guy is I wonder how he makes the time to do so much reading and thinking on things. Thankfully I can read his blog so that I don&amp;#8217;t have to think about them : ). Also good to note that &lt;a href="http://bulknews.typepad.com"&gt;Miyagawa&lt;/a&gt; has taken yet another &lt;a href="http://bulknews.typepad.com/blog/2010/01/plack-099-and-10-milestones.html"&gt;step closer to a version 1.0 release of Plack&lt;/a&gt; (&lt;a href="http://plackperl.org/"&gt;Plack the Perl Web Server&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;Cultured Perlers&lt;/h2&gt;
&lt;p&gt;In a bold move I have decided that I will start yet another blog initiative (I currently blog to 4 places, some more than others which are all linked from flavors.me/mdk) if &lt;a href="http://perlhacks.com/"&gt;Dave Cross&lt;/a&gt; gets his &lt;a href="http://perlhacks.com/2010/02/cultured-perl-blog.php"&gt;Cultured Perl&lt;/a&gt; site up and running. I like the idea and have expressed the need for more introduction/promotion of the Perl community to a wider world and expressed this as part of my keynote, so I felt obliged to join in. My only concern will be the overlap with this blog and the strain on my limited writing capabilities. But, hey ho, we will see what happens. Hopefully Dave will let us all know soon what is going on.&lt;/p&gt;
&lt;p&gt;That wraps up my week of &lt;a href="http://ironman.enlightenedperl.org/"&gt;Ironman posts&lt;/a&gt; that I needed to share with you.&lt;/p&gt;
&lt;p&gt;-ttfn &amp;#8211; Mark&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ironman.enlightenedperl.org/signup/new_feed"&gt;&lt;img src="http://mdk.per.ly/files/2009/09/ironsignup.png" alt="ironsignup"&gt;&lt;/a&gt;&lt;/p&gt;
</content>
    <category term="Ironman Perl The Perl Foundation Mark Keating Plack TPF"/>
    <published>2010-02-03T16:29:12+02:00</published>
    <updated>2010-02-03T16:29:12+02:00</updated>
    <author>
      <name>mdk</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://mdk.per.ly/?p=399</id>
  </entry>
  <entry>
    <title>Perl and Mac OS X versions</title>
    <link rel="alternate" href="http://transfixedbutnotdead.com/2010/02/03/perl-and-mac-os-x-versions/" type="text/html"/>
    <summary type="text">Apple website has an opensource page: http://www.opensource.apple.com/,
which lists all its products and components which have and use opensource
technology.

If you go here: http://www.apple.com/opensource/, it provides a complete
list of opensource projects that Apple uses.

In this list is of course Perl. From this we can see which version of
Perl was compiled on Mac OS X. We can also see what options, patches,
fixes &amp; extra modules were included.

So I’ve been able to glean these Perl versions that Apple have used with
Mac OS X:

  * 5.10.0 &amp; 5.8.9 (perl-63)

  * 5.8.8 (perl-51 patches: perl-51.1.1, perl-51.1.4)

  * 5.8.6 (perl-38 patch: perl-38.1)

  * 5.8.6 (perl-35 patch: perl-35.1.1)

  * 5.8.4 (perl-28.2)

  * 5.8.1-RC3 (perl-25.2)

  * 5.8.1 (perl-24.1) “Maintenance release working toward v5.8.1″

  * 5.6.0 (perl-21)

  * 5.6.0 (perl-17)

Now which one(s) are tied to which Mac OS X is still in the air a bit!
This is my best stab at it:

  10.6    5.10.0 &amp; 5.8.9      perl-63
  10.5    5.8.8               perl-51
  10.4    5.8.6               perl-38 or perl-35
  10.3    5.8.4 or 5.8.1 ?
  10.2    5.8.1 ?
  10.1    5.6.0               ? perl-21 and/or perl-17
  10.0    5.6.0 ?

Hopefully this information is useful to someone

/I3az/

refs:

  * Mac OS X “Snow Leopard” (10.6) and Perl

  * Apple Open Source (Hacker News)

  *</summary>
    <content type="html">&lt;div class="snap_preview"&gt;&lt;br /&gt;&lt;p&gt;Apple website has an opensource page: &lt;a href="http://www.opensource.apple.com/"&gt;http://www.opensource.apple.com/&lt;/a&gt;, which lists all its products and components which have and use opensource technology.&lt;/p&gt;
&lt;p&gt;If you go here: &lt;a href="http://www.apple.com/opensource/"&gt;http://www.apple.com/opensource/&lt;/a&gt;, it provides a complete list of opensource projects that Apple uses.  &lt;/p&gt;
&lt;p&gt;In this list is of course &lt;a href="http://www.opensource.apple.com/source/perl/"&gt;Perl&lt;/a&gt;.  From this we can see which version of Perl was compiled on Mac OS X.  We can also see what options, patches, fixes &amp;amp; extra modules were included.&lt;/p&gt;
&lt;p&gt;So I&amp;#8217;ve been able to glean these Perl versions that Apple have used with Mac OS X:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5.10.0 &amp;amp; 5.8.9		(perl-63)&lt;/li&gt;
&lt;li&gt;5.8.8				(perl-51 patches: perl-51.1.1, perl-51.1.4)&lt;/li&gt;
&lt;li&gt;5.8.6				(perl-38 patch: perl-38.1)	&lt;/li&gt;
&lt;li&gt;5.8.6	(perl-35 patch: perl-35.1.1)&lt;/li&gt;
&lt;li&gt;5.8.4	(perl-28.2)&lt;/li&gt;
&lt;li&gt;5.8.1-RC3	(perl-25.2)&lt;/li&gt;
&lt;li&gt;5.8.1	(perl-24.1)	&amp;#8220;Maintenance release working toward v5.8.1&amp;#8243;&lt;/li&gt;
&lt;li&gt;5.6.0	(perl-21)&lt;/li&gt;
&lt;li&gt;5.6.0	(perl-17)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now which one(s) are tied to which Mac OS X is still in the air a bit!  This is my best stab at it:&lt;/p&gt;
&lt;pre&gt;
  10.6    5.10.0 &amp;amp; 5.8.9      perl-63
  10.5    5.8.8               perl-51
  10.4    5.8.6               perl-38 or perl-35
  10.3    5.8.4 or 5.8.1 ?
  10.2    5.8.1 ?
  10.1    5.6.0               ? perl-21 and/or perl-17
  10.0    5.6.0 ?
&lt;/pre&gt;
&lt;p&gt;Hopefully this information is &lt;a href="http://stackoverflow.com/questions/2092944/how-can-i-find-out-which-perl-version-was-available-on-older-mac-os-x-versions"&gt;useful to someone&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;/I3az/&lt;/p&gt;
&lt;p&gt;refs: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://transfixedbutnotdead.com/2010/01/24/mac-os-x-snow-leopard-10-6-and-perl/"&gt;Mac OS X “Snow Leopard” (10.6) and Perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://news.ycombinator.com/item?id=1095075"&gt;Apple Open Source (Hacker News)&lt;/a&gt;
&lt;li&gt;
&lt;/ul&gt;
  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/draegtun.wordpress.com/836/"&gt;&lt;img alt="" src="http://feeds.wordpress.com/1.0/comments/draegtun.wordpress.com/836/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/draegtun.wordpress.com/836/"&gt;&lt;img alt="" src="http://feeds.wordpress.com/1.0/delicious/draegtun.wordpress.com/836/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/draegtun.wordpress.com/836/"&gt;&lt;img alt="" src="http://feeds.wordpress.com/1.0/stumble/draegtun.wordpress.com/836/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/draegtun.wordpress.com/836/"&gt;&lt;img alt="" src="http://feeds.wordpress.com/1.0/digg/draegtun.wordpress.com/836/"&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/draegtun.wordpress.com/836/"&gt;&lt;img alt="" src="http://feeds.wordpress.com/1.0/reddit/draegtun.wordpress.com/836/"&gt;&lt;/a&gt; &lt;img alt="" src="http://stats.wordpress.com/b.gif?host=transfixedbutnotdead.com&amp;amp;blog=351142&amp;amp;post=836&amp;amp;subd=draegtun&amp;amp;ref=&amp;amp;feed=1"&gt;&lt;/div&gt;</content>
    <category term="Programming Tech Mac OSX perl"/>
    <published>2010-02-03T10:42:05Z</published>
    <updated>2010-02-03T10:42:05Z</updated>
    <author>
      <name>draegtun</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://transfixedbutnotdead.com/?p=836</id>
    <link xmlns="http://purl.org/atom/ns#" rel="enclosure" type="" href="" length=""/>
  </entry>
  <entry>
    <title>which module to extract perl prereqs?</title>
    <link rel="alternate" href="http://jquelin.blogspot.com/2010/02/which-module-to-extract-perl-prereqs.html" type="text/html"/>
    <summary type="text">in dzil plugin autoprereq, i'm extracting prereqs from the dist modules.
i want this extract to be fast, based on the actual code (not makefile.pl
or meta.yml, since the goal is to generate them), and as accurate as
possible. it should also find base classes, moose roles and other
"hidden" dependencies. finally, it should extract the minimum version
needed for a given module, including minimum perl version.

my first version was regex-based. i can already see your horrified face -
but really it wasn't so bad, since it only needed to find some specific
statements such as uses and requires. current version is using ppi, which
is better suited for corner cases.

however, long-term makes me think that it would be better to rely on an
external module. so, what are the alternatives out there on cpan, and can
i use them in autoprereq?

  * b::perlreq - parses the file, but reports file (File/Basename.pm)
    instead of modules, and is generally more suited for rpm

  * module::extract::use - using ppi to parse a file, but extracts only
    use &amp; require statements (no inheritance, moose roles, etc). also, it
    reports no minimum version extraction, only a list of modules.

  * test::dependencies - using either b::perlreq (see above) or a regex
    scheme underneath

  * module::scandeps - runs the file (which is slow), and finds all
    modules included - and sometimes a bit more (eg:
    file::homeDir::darwin is found for a module using file::homedir, even
    on a unix platform). can also run as a static analyser, but calls
    cpanplus (?!) which is slow.

  * module::info - regex based

  * module::cpants::generator::prereq - parses makefile.pl, where i want
    sthg that parses actual code

  * module::cpants::kwalitee::prereq - parse meta.yml, makefile.pl or
    build.pl

so, no module was doing exactly what i wanted... since i am using ppi and
that module::extract::use does the same, i contacted brian d foy to see
whether he would be interested in additional extractions (moose roles,
base classes, etc.) for this module. he was, so those enhancements are
now pushed on my github clone.

i'm now waiting for a new release of this module with my enhancements,
meaning that i can get rid of this part of the code in dzil autoprereq.
which was, if you recall, the original goal! :-)</summary>
    <content type="text">in &lt;a href="http://search.cpan.org/dist/Dist-Zilla"&gt;dzil&lt;/a&gt; plugin &lt;a href="http://search.cpan.org/perldoc?Dist::Zilla::Plugin::AutoPrereq"&gt;autoprereq&lt;/a&gt;, i'm extracting prereqs from the dist modules. i want this extract to be fast, based on the actual code (not makefile.pl or meta.yml, since the goal is to generate them), and as accurate as possible. it should also find base classes, moose roles and other "hidden" dependencies. finally, it should extract the minimum version needed for a given module, including minimum perl version.&lt;br /&gt;&lt;br /&gt;my first version was regex-based. i can already see your horrified face - but really it wasn't so bad, since it only needed to find some specific statements such as uses and requires. current version is using &lt;a href="http://search.cpan.org/perldoc?PPI"&gt;ppi&lt;/a&gt;, which is better suited for corner cases.&lt;br /&gt;&lt;br /&gt;however, long-term makes me think that it would be better to rely on an external module. so, what are the alternatives out there on cpan, and can i use them in autoprereq?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?B::PerlReq"&gt;b::perlreq&lt;/a&gt; - parses the file, but reports file (&lt;span&gt;File/Basename.pm&lt;/span&gt;) instead of modules, and is generally more suited for rpm&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?Module::Extract::Use"&gt;module::extract::use&lt;/a&gt; - using ppi to parse a file, but extracts only use &amp;amp; require statements (no inheritance, moose roles, etc). also, it reports no minimum version extraction, only a list of modules.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?Test::Dependencies"&gt;test::dependencies&lt;/a&gt; - using either b::perlreq (see above) or a regex scheme underneath&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?Module::ScanDeps"&gt;module::scandeps&lt;/a&gt; - runs the file (which is slow), and finds all modules included - and sometimes a bit more (eg: file::homeDir::darwin is found for a module using file::homedir, even on a unix platform). can also run as a static analyser, but calls cpanplus (?!) which is slow.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?Module::Info"&gt;module::info&lt;/a&gt; - regex based&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?Module::CPANTS::Generator::Prereq"&gt;module::cpants::generator::prereq&lt;/a&gt; - parses makefile.pl, where i want sthg that parses actual code&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?Module::CPANTS::Kwalitee::Prereq"&gt;module::cpants::kwalitee::prereq&lt;/a&gt; - parse meta.yml, makefile.pl or build.pl&lt;/li&gt;&lt;/ul&gt;so, no module was doing exactly what i wanted... since i am using ppi and that module::extract::use does the same, i contacted brian d foy to see whether he would be interested in additional extractions (moose roles, base classes, etc.) for this module. he was, so those enhancements are now pushed on my &lt;a href="http://github.com/jquelin/module--extract--use"&gt;github clone&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;i'm now waiting for a new release of this module with my enhancements, meaning that i can get rid of this part of the code in dzil autoprereq. which was, if you recall, the original goal! :-)&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="moose dzill dist perl prereqs"/>
    <published>2010-02-03T10:09:00Z</published>
    <updated>2010-02-03T10:09:00Z</updated>
    <author>
      <name>Jérôme Quelin</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-6162910877268067002.post-1265540343122634519</id>
  </entry>
  <entry>
    <title>Всякая всячина и книги</title>
    <link rel="alternate" href="http://laziness-impatience-hubris.blogspot.com/2010/02/blog-post.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Пора заканчивать заниматься ерундой и писать всякую фигню o Perl - блог
закрыт. Сажусь за написание двух книг.

Первая книга будет называется "Событийное программирование на Perl для
домохозяек или как успеть приготовить тысячу блюд к приходу гостей".

Вторая - "Распределенное программирование на Perl для домохозяек".
Эта книга предназначена для тех, кто любому кухонному комбайну
предпочитает набор хороших кухонных ножей.

Логичней было начать с первой, но вторая сейчас интересней, поэтому есть
большая вероятность, что первая будет лишь брошюркой.

Здесь будет опубликованы анонсы. До встречи.</div>
    </summary>
    <content type="text">Пора заканчивать заниматься ерундой и писать всякую фигню o Perl - блог закрыт. Сажусь за написание двух книг.&lt;br /&gt;&lt;br /&gt;Первая книга будет называется "Событийное программирование на Perl для домохозяек или как успеть приготовить тысячу блюд к приходу гостей".&lt;br /&gt;&lt;br /&gt;Вторая - "Распределенное программирование на Perl для домохозяек".&lt;br /&gt;Эта книга предназначена для тех, кто любому кухонному комбайну предпочитает набор хороших кухонных ножей.&lt;br /&gt;&lt;br /&gt;Логичней было начать с первой, но вторая сейчас интересней, поэтому есть большая вероятность, что первая будет лишь брошюркой.&lt;br /&gt;&lt;br /&gt;Здесь будет опубликованы анонсы. До встречи.&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="perl"/>
    <published>2010-02-03T09:15:00Z</published>
    <updated>2010-02-03T09:15:00Z</updated>
    <author>
      <name>Nick</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-7498141530276954327.post-9049254266324196332</id>
  </entry>
  <entry>
    <title>Famous Perl One-Liners Explained, Part V: Text conversion and substitution</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/catonmat/~3/ZepRCtiIfC8/" type="text/html"/>
    <summary type="text">[IMAGE]
[IMAGE]

Perl One LinersThis is the fifth part of a nine-part article on famous
Perl one-liners. In this part I will create various one-liners for text
conversion and substitution. See part one for introduction of the series.

Famous Perl one-liners is my attempt to create “perl1line.txt” that is
similar to “awk1line.txt” and “sed1line.txt” that have been so popular
among Awk and Sed programmers.

The article on famous Perl one-liners will consist of nine parts:

  * Part I: File spacing.

  * Part II: Line numbering.

  * Part III: Calculations.

  * Part IV: String creation and array creation.

  * Part V: Text conversion and substitution (this part).

  * Part VI: Selective printing and deleting of certain lines.

  * Part VII: Handy regular expressions.

  * Part VIII: Release of perl1line.txt.

  * Part IX: Release of Perl One-Liners e-book.

Everyone who’s subscribed to my blog will get a free copy of Perl
One-Liners e-book when I release it as part 9 of this article series!

Alright then, here are today’s one-liners:


Text conversion and substitution
--------------------------------

62. ROT13 a string.

'y/A-Za-z/N-ZA-Mn-za-m/'

This one-liner uses the y operator (also known as tr operator) to do
ROT13. Operators y and tr do string transliteration. Given
y/SEARCH/REPLACE/, the operator transliterates all occurrences of the
characters found in SEARCH list with the corresponding (position-wise)
characters in REPLACE list.

In this one-liner A-Za-z creates the following list of characters:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

And N-ZA-Mn-za-m creates this list:

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

If you look closely you’ll notice that the second list is actually the
first list offset by 13 characters. Now the y operator translates each
character in the first list to a character in the second list, thus
performing the ROT13 operation.

If you wish to ROT13 the whole file then do this:

perl -lpe 'y/A-Za-z/N-ZA-Mn-za-m/' file

The -p argument puts each of file’s line in the $_ variable, the y does
ROT13, and -p prints the $_ out. The -l appends a newline to the output.

Note: remember that applying ROT13 twice produces the same string, i.e.,
ROT13(ROT13(string)) == string.

63. Base64 encode a string.

perl -MMIME::Base64 -e 'print encode_base64("string")'

This one-liner uses the MIME::Base64 module that is in the core (no need
to install it, it comes with Perl). This module exports the encode_base64
function that takes a string and returns base64 encoded version of it.

To base64 encode the whole file do the following:

perl -MMIME::Base64 -0777 -ne 'print encode_base64($_)' file

Here the -0777 argument together with -n causes Perl to slurp the whole
file into the $_ variable. Then the file gets base64 encoded and printed
out, just like the string example above.

If we didn’t slurp the file and encoded it line-by-line we’d get a mess.

64. Base64 decode a string.

perl -MMIME::Base64 -le 'print decode_base64("base64string")'

The MIME::Base64 module also exports decode_base64 function that takes a
base64-encoded string and decodes it.

The whole file can be similarly decoded by:

perl -MMIME::Base64 -ne 'print decode_base64($_)' file

There is no need to slurp the whole file into $_ because each line of a
base64 encoded file is exactly 76 characters and decodes nicely.

65. URL-escape a string.

perl -MURI::Escape -le 'print uri_escape($string)'

You’ll need to install the URI::Escape module as it doesn’t come with
Perl. The module exports two functions - uri_escape and uri_unescape. The
first one does URL-escaping (sometimes also referred to as URL encoding),
and the other does URL-unescaping (URL decoding).

66. URL-unescape a string.

perl -MURI::Escape -le 'print uri_unescape($string)'

This one-liner uses the uri_unescape function from URI::Escape module to
do URL-unescaping.

67. HTML-encode a string.

perl -MHTML::Entities -le 'print encode_entities($string)'

This one-liner uses the encode_entities function from HTML::Entities
module. This function encodes HTML entities. For example, &lt; and &gt; get
turned into &amp;lt; and &amp;gt;.

68. HTML-decode a string.

perl -MHTML::Entities -le 'print decode_entities($string)'

This one-liner uses the decode_entities function from HTML::Entities
module.

69. Convert all text to uppercase.

perl -nle 'print uc'

This one-liner uses the uc function, which by default operates on the $_
variable and returns an uppercase version of it.

Another way to do the same is to use -p command line option that enables
automatic printing of $_ variable and modify it in-place:

perl -ple '$_=uc'

The same can also be also achieved by applying the \U escape sequence to
string interpolation:

perl -nle 'print "\U$_"'

It causes anything after it (or until the first occurrence of \E) to be
upper-cased.

70. Convert all text to lowercase.

perl -nle 'print lc'

This one-liner is very similar to the previous. Here the lc function is
used that converts the contents of $_ to lowercase.

Or, using escape sequence \L and string interpolation:

perl -nle 'print "\L$_"'

Here \L causes everything after it (until the first occurrence of \E) to
be lower-cased.

71. Uppercase only the first word of each line.

perl -nle 'print ucfirst lc'

The one-liner first applies the lc function to the input that makes it
lower case and then uses the ucfirst function that upper-cases only the
first character.

It can also be done via escape codes and string interpolation:

perl -nle 'print "\u\L$_"'

First the \L lower-cases the whole line, then \u upper-cases the first
character.

72. Invert the letter case.

perl -ple 'y/A-Za-z/a-zA-Z/'

This one-liner does transliterates capital letters A-Z to lowercase
letters a-z, and lowercase letters to uppercase letters, thus switching
the case.

73. Camel case each line.

perl -ple 's/(\w+)/\u$1/g'

This is a lousy Camel Casing one-liner. It takes each word and
upper-cases the first letter of it. It fails on possessive forms like
“friend’s car”. It turns them into “Friend’S Car”.

An improvement is:

s/(?&lt;!['])(\w+)/\u\1/g

Which checks if the character before the word is not single quote '. But
I am sure it still fails on some more exotic examples.

74. Strip leading whitespace (spaces, tabs) from the beginning of each
line.

perl -ple 's/^[ \t]+//'

This one-liner deletes all whitespace from the beginning of each line. It
uses the substitution operator s. Given s/REGEX/REPLACE/ it replaces the
matched REGEX by the REPLACE string. In this case the REGEX is ^[ \t]+,
which means “match one or more space or tab at the beginning of the
string” and REPLACE is nothing, meaning, replace the matched part with
empty string.

The regex class [ \t] can actually be replaced by \s+ that matches any
whitespace (including tabs and spaces):

perl -ple 's/^\s+//'

75. Strip trailing whitespace (space, tabs) from the end of each line.

perl -ple 's/[ \t]+$//'

This one-liner deletes all whitespace from the end of each line.

Here the REGEX of the s operator says “match one or more space or tab at
the end of the string.” The REPLACE part is empty again, which means to
erase the matched whitespace.

76. Strip whitespace from the beginning and end of each line.

perl -ple 's/^[ \t]+|[ \t]+$//g'

This one-liner combines the previous two. Notice that it specifies the
global /g flag to the s operator. It’s necessary because we want it to
delete whitespace at the beginning AND end of the string. If we didn’t
specify it, it would only delete whitespace at the beginning (assuming it
exists) and not at the end.

77. Convert UNIX newlines to DOS/Windows newlines.

perl -pe 's|\n|\r\n|'

This one-liner substitutes the Unix newline \n LF with Windows newline
\r\n CRLF on each line. Remember that the s operator can use anything for
delimiters. In this one-liner it uses vertical pipes to delimit REGEX
from REPLACE to improve readibility.

78. Convert DOS/Windows newlines to UNIX newlines.

perl -pe 's|\r\n|\n|'

This one-liner does the opposite of the previous one. It takes Windows
newlines CRLF and converts them to Unix newlines LF.

79. Convert UNIX newlines to Mac newlines.

perl -pe 's|\n|\r|'

Apple Macintoshes used to use \r CR as newlines. This one-liner converts
UNIX’s \n to Mac’s \r.

80. Substitute (find and replace) “foo” with “bar” on each line.

perl -pe 's/foo/bar/'

This one-liner uses the s/REGEX/REPLACE/ command to substitute “foo” with
“bar” on each line.

To replace all “foos” with “bars”, add the global /g flag:

perl -pe 's/foo/bar/g'

81. Substitute (find and replace) “foo” with “bar” on lines that match
“baz”.

perl -pe '/baz/ &amp;&amp; s/foo/bar/'

This one-liner is equivalent to:

while (defined($line = &lt;&gt;)) {
  if ($line =~ /baz/) {
    $line =~ s/foo/bar/
  }
}

It puts each line in variable $line, then checks if line matches “baz”,
and if it does, it replaces “foo” with “bar” in it.


Got tired.
----------

I got tired of writing one-liners at this moment. I’ll update this
article the same way I did the 3rd part - I’ll add a few new one-liners
each week until the article is finished.


Have Fun!
---------

Have fun with these one-liners for now. The next part is going to be
about selective printing and deleting of certain lines.

Can you think of other text conversion and substitution procedures that I
did not include here?

[IMAGE] [IMAGE] [IMAGE] [IMAGE][IMAGE]</summary>
    <content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dxsQzc-tI1BwfGVg3Wu2IgH2WAo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dxsQzc-tI1BwfGVg3Wu2IgH2WAo/0/di"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dxsQzc-tI1BwfGVg3Wu2IgH2WAo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dxsQzc-tI1BwfGVg3Wu2IgH2WAo/1/di"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.catonmat.net/blog/wp-content/uploads/2009/02/perl-one-liners.jpg" alt="Perl One Liners"&gt;This is the fifth part of a nine-part article on &lt;strong&gt;famous Perl one-liners&lt;/strong&gt;. In this part I will create various one-liners for &lt;strong&gt;text conversion and substitution&lt;/strong&gt;. See &lt;a href="http://www.catonmat.net/blog/perl-one-liners-explained-part-one/"&gt;part one&lt;/a&gt; for introduction of the series.&lt;/p&gt;
&lt;p&gt;Famous Perl one-liners is my attempt to create &amp;#8220;&lt;strong&gt;perl1line.txt&lt;/strong&gt;&amp;#8221; that is similar to &amp;#8220;&lt;a href="http://www.catonmat.net/blog/awk-one-liners-explained-part-one/"&gt;awk1line.txt&lt;/a&gt;&amp;#8221; and &amp;#8220;&lt;a href="http://www.catonmat.net/blog/sed-one-liners-explained-part-one/"&gt;sed1line.txt&lt;/a&gt;&amp;#8221; that have been so popular among Awk and Sed programmers.&lt;/p&gt;
&lt;p&gt;The article on famous Perl one-liners will consist of nine parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.catonmat.net/blog/perl-one-liners-explained-part-one/"&gt;Part I: File spacing.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.catonmat.net/blog/perl-one-liners-explained-part-two/"&gt;Part II: Line numbering.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.catonmat.net/blog/perl-one-liners-explained-part-three/"&gt;Part III: Calculations.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.catonmat.net/blog/perl-one-liners-explained-part-four/"&gt;Part IV: String creation and array creation.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part V: Text conversion and substitution (this part).&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Part VI: Selective printing and deleting of certain lines.&lt;/li&gt;
&lt;li&gt;Part VII: Handy regular expressions.&lt;/li&gt;
&lt;li&gt;Part VIII: Release of perl1line.txt.&lt;/li&gt;
&lt;li&gt;Part IX: Release of Perl One-Liners e-book.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everyone who&amp;#8217;s &lt;a href="http://www.catonmat.net/feed/"&gt;subscribed to my blog&lt;/a&gt; will get a &lt;strong&gt;free copy of Perl One-Liners e-book&lt;/strong&gt; when I release it as part 9 of this article series!&lt;/p&gt;
&lt;p&gt;Alright then, here are today&amp;#8217;s one-liners:&lt;/p&gt;
&lt;h2&gt;Text conversion and substitution&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;62. ROT13 a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;'y/A-Za-z/N-ZA-Mn-za-m/'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;code&gt;y&lt;/code&gt; operator (also known as &lt;code&gt;tr&lt;/code&gt; operator) to do ROT13. Operators &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;tr&lt;/code&gt; do string transliteration. Given &lt;code&gt;y/SEARCH/REPLACE/&lt;/code&gt;, the operator transliterates all occurrences of the characters found in &lt;code&gt;SEARCH&lt;/code&gt; list with the corresponding (position-wise) characters in &lt;code&gt;REPLACE&lt;/code&gt; list.&lt;/p&gt;
&lt;p&gt;In this one-liner &lt;code&gt;A-Za-z&lt;/code&gt; creates the following list of characters:&lt;/p&gt;
&lt;pre&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&lt;/pre&gt;
&lt;p&gt;And &lt;code&gt;N-ZA-Mn-za-m&lt;/code&gt; creates this list:&lt;/p&gt;
&lt;pre&gt;NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm&lt;/pre&gt;
&lt;p&gt;If you look closely you&amp;#8217;ll notice that the second list is actually the first list offset by 13 characters. Now the &lt;code&gt;y&lt;/code&gt; operator translates each character in the first list to a character in the second list, thus performing the ROT13 operation.&lt;/p&gt;
&lt;p&gt;If you wish to ROT13 the whole file then do this:&lt;/p&gt;
&lt;pre&gt;perl -lpe 'y/A-Za-z/N-ZA-Mn-za-m/' file&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;-p&lt;/code&gt; argument puts each of &lt;code&gt;file&lt;/code&gt;&amp;#8217;s line in the &lt;code&gt;$_&lt;/code&gt; variable, the &lt;code&gt;y&lt;/code&gt; does ROT13, and &lt;code&gt;-p&lt;/code&gt; prints the &lt;code&gt;$_&lt;/code&gt; out. The &lt;code&gt;-l&lt;/code&gt; appends a newline to the output.&lt;/p&gt;
&lt;p&gt;Note: remember that applying ROT13 twice produces the same string, i.e., &lt;code&gt;ROT13(ROT13(string)) == string&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;63. Base64 encode a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -MMIME::Base64 -e 'print encode_base64("string")'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;a href="http://search.cpan.org/~gaas/MIME-Base64-3.09/Base64.pm"&gt;MIME::Base64&lt;/a&gt; module that is in the core (no need to install it, it comes with Perl). This module exports the &lt;code&gt;encode_base64&lt;/code&gt; function that takes a string and returns base64 encoded version of it.&lt;/p&gt;
&lt;p&gt;To base64 encode the whole file do the following:&lt;/p&gt;
&lt;pre&gt;perl -MMIME::Base64 -0777 -ne 'print encode_base64($_)' file&lt;/pre&gt;
&lt;p&gt;Here the &lt;code&gt;-0777&lt;/code&gt; argument together with &lt;code&gt;-n&lt;/code&gt; causes Perl to slurp the whole file into the &lt;code&gt;$_&lt;/code&gt; variable. Then the file gets base64 encoded and printed out, just like the string example above.&lt;/p&gt;
&lt;p&gt;If we didn&amp;#8217;t slurp the file and encoded it line-by-line we&amp;#8217;d get a mess.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;64. Base64 decode a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -MMIME::Base64 -le 'print decode_base64("base64string")'&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;MIME::Base64&lt;/code&gt; module also exports &lt;code&gt;decode_base64&lt;/code&gt; function that takes a base64-encoded string and decodes it.&lt;/p&gt;
&lt;p&gt;The whole file can be similarly decoded by:&lt;/p&gt;
&lt;pre&gt;perl -MMIME::Base64 -ne 'print decode_base64($_)' file&lt;/pre&gt;
&lt;p&gt;There is no need to slurp the whole file into &lt;code&gt;$_&lt;/code&gt; because each line of a base64 encoded file is exactly 76 characters and decodes nicely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;65. URL-escape a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -MURI::Escape -le 'print uri_escape($string)'&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll need to install the &lt;a href="http://search.cpan.org/~gaas/URI-1.52/URI/Escape.pm"&gt;URI::Escape&lt;/a&gt; module as it doesn&amp;#8217;t come with Perl. The module exports two functions - &lt;code&gt;uri_escape&lt;/code&gt; and &lt;code&gt;uri_unescape&lt;/code&gt;. The first one does URL-escaping (sometimes also referred to as URL encoding), and the other does URL-unescaping (URL decoding).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;66. URL-unescape a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -MURI::Escape -le 'print uri_unescape($string)'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;code&gt;uri_unescape&lt;/code&gt; function from &lt;code&gt;URI::Escape&lt;/code&gt; module to do URL-unescaping.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;67. HTML-encode a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -MHTML::Entities -le 'print encode_entities($string)'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;code&gt;encode_entities&lt;/code&gt; function from &lt;a href="http://search.cpan.org/~gaas/HTML-Parser-3.64/lib/HTML/Entities.pm"&gt;HTML::Entities&lt;/a&gt; module. This function encodes HTML entities. For example, &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; get turned into &lt;code&gt;&amp;amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;68. HTML-decode a string.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -MHTML::Entities -le 'print decode_entities($string)'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;code&gt;decode_entities&lt;/code&gt; function from &lt;code&gt;HTML::Entities&lt;/code&gt; module.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;69. Convert all text to uppercase.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -nle 'print uc'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;code&gt;uc&lt;/code&gt; function, which by default operates on the &lt;code&gt;$_&lt;/code&gt; variable and returns an uppercase version of it.&lt;/p&gt;
&lt;p&gt;Another way to do the same is to use &lt;code&gt;-p&lt;/code&gt; command line option that enables automatic printing of &lt;code&gt;$_&lt;/code&gt; variable and modify it in-place:&lt;/p&gt;
&lt;pre&gt;perl -ple '$_=uc'&lt;/pre&gt;
&lt;p&gt;The same can also be also achieved by applying the &lt;code&gt;\U&lt;/code&gt; escape sequence to string interpolation:&lt;/p&gt;
&lt;pre&gt;perl -nle 'print "\U$_"'&lt;/pre&gt;
&lt;p&gt;It causes anything after it (or until the first occurrence of &lt;code&gt;\E&lt;/code&gt;) to be upper-cased.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;70. Convert all text to lowercase.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -nle 'print lc'&lt;/pre&gt;
&lt;p&gt;This one-liner is very similar to the previous. Here the &lt;code&gt;lc&lt;/code&gt; function is used that converts the contents of &lt;code&gt;$_&lt;/code&gt; to lowercase.&lt;/p&gt;
&lt;p&gt;Or, using escape sequence &lt;code&gt;\L&lt;/code&gt; and string interpolation:&lt;/p&gt;
&lt;pre&gt;perl -nle 'print "\L$_"'&lt;/pre&gt;
&lt;p&gt;Here &lt;code&gt;\L&lt;/code&gt; causes everything after it (until the first occurrence of &lt;code&gt;\E&lt;/code&gt;) to be lower-cased.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;71. Uppercase only the first word of each line.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -nle 'print ucfirst lc'&lt;/pre&gt;
&lt;p&gt;The one-liner first applies the &lt;code&gt;lc&lt;/code&gt; function to the input that makes it lower case and then uses the &lt;code&gt;ucfirst&lt;/code&gt; function that upper-cases only the first character.&lt;/p&gt;
&lt;p&gt;It can also be done via escape codes and string interpolation:&lt;/p&gt;
&lt;pre&gt;perl -nle 'print "\u\L$_"'&lt;/pre&gt;
&lt;p&gt;First the &lt;code&gt;\L&lt;/code&gt; lower-cases the whole line, then &lt;code&gt;\u&lt;/code&gt; upper-cases the first character.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;72. Invert the letter case.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -ple 'y/A-Za-z/a-zA-Z/'&lt;/pre&gt;
&lt;p&gt;This one-liner does transliterates capital letters &lt;code&gt;A-Z&lt;/code&gt; to lowercase letters &lt;code&gt;a-z&lt;/code&gt;, and lowercase letters to uppercase letters, thus switching the case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;73. Camel case each line.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -ple 's/(\w+)/\u$1/g'&lt;/pre&gt;
&lt;p&gt;This is a lousy Camel Casing one-liner. It takes each word and upper-cases the first letter of it. It fails on possessive forms like &amp;#8220;friend&amp;#8217;s car&amp;#8221;. It turns them into &amp;#8220;Friend&amp;#8217;S Car&amp;#8221;.&lt;/p&gt;
&lt;p&gt;An improvement is:&lt;/p&gt;
&lt;pre&gt;s/(?&amp;lt;!['])(\w+)/\u\1/g&lt;/pre&gt;
&lt;p&gt;Which checks if the character before the word is not single quote &lt;code&gt;'&lt;/code&gt;. But I am sure it still fails on some more exotic examples.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;74. Strip leading whitespace (spaces, tabs) from the beginning of each line.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -ple 's/^[ \t]+//'&lt;/pre&gt;
&lt;p&gt;This one-liner deletes all whitespace from the beginning of each line. It uses the substitution operator &lt;code&gt;s&lt;/code&gt;. Given &lt;code&gt;s/REGEX/REPLACE/&lt;/code&gt; it replaces the matched &lt;code&gt;REGEX&lt;/code&gt; by the &lt;code&gt;REPLACE&lt;/code&gt; string. In this case the &lt;code&gt;REGEX&lt;/code&gt; is &lt;code&gt;^[ \t]+&lt;/code&gt;, which means &amp;#8220;match one or more space or tab at the beginning of the string&amp;#8221; and &lt;code&gt;REPLACE&lt;/code&gt; is nothing, meaning, replace the matched part with empty string.&lt;/p&gt;
&lt;p&gt;The regex class &lt;code&gt;[ \t]&lt;/code&gt; can actually be replaced by &lt;code&gt;\s+&lt;/code&gt; that matches any whitespace (including tabs and spaces):&lt;/p&gt;
&lt;pre&gt;perl -ple 's/^\s+//'&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;75. Strip trailing whitespace (space, tabs) from the end of each line.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -ple 's/[ \t]+$//'&lt;/pre&gt;
&lt;p&gt;This one-liner deletes all whitespace from the end of each line.&lt;/p&gt;
&lt;p&gt;Here the &lt;code&gt;REGEX&lt;/code&gt; of the &lt;code&gt;s&lt;/code&gt; operator says &amp;#8220;match one or more space or tab at the end of the string.&amp;#8221; The &lt;code&gt;REPLACE&lt;/code&gt; part is empty again, which means to erase the matched whitespace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;76. Strip whitespace from the beginning and end of each line.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -ple 's/^[ \t]+|[ \t]+$//g'&lt;/pre&gt;
&lt;p&gt;This one-liner combines the previous two. Notice that it specifies the global &lt;code&gt;/g&lt;/code&gt; flag to the &lt;code&gt;s&lt;/code&gt; operator. It&amp;#8217;s necessary because we want it to delete whitespace at the beginning AND end of the string. If we didn&amp;#8217;t specify it, it would only delete whitespace at the beginning (assuming it exists) and not at the end.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;77. Convert UNIX newlines to DOS/Windows newlines.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -pe 's|\n|\r\n|'&lt;/pre&gt;
&lt;p&gt;This one-liner substitutes the Unix newline &lt;code&gt;\n&lt;/code&gt; LF with Windows newline &lt;code&gt;\r\n&lt;/code&gt; CRLF on each line. Remember that the &lt;code&gt;s&lt;/code&gt; operator can use anything for delimiters. In this one-liner it uses vertical pipes to delimit &lt;code&gt;REGEX&lt;/code&gt; from &lt;code&gt;REPLACE&lt;/code&gt; to improve readibility. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;78. Convert DOS/Windows newlines to UNIX newlines.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -pe 's|\r\n|\n|'&lt;/pre&gt;
&lt;p&gt;This one-liner does the opposite of the previous one. It takes Windows newlines CRLF and converts them to Unix newlines LF.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;79. Convert UNIX newlines to Mac newlines.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -pe 's|\n|\r|'&lt;/pre&gt;
&lt;p&gt;Apple Macintoshes used to use &lt;code&gt;\r&lt;/code&gt; CR as newlines. This one-liner converts UNIX&amp;#8217;s &lt;code&gt;\n&lt;/code&gt; to Mac&amp;#8217;s &lt;code&gt;\r&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;80. Substitute (find and replace) &amp;#8220;foo&amp;#8221; with &amp;#8220;bar&amp;#8221; on each line.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -pe 's/foo/bar/'&lt;/pre&gt;
&lt;p&gt;This one-liner uses the &lt;code&gt;s/REGEX/REPLACE/&lt;/code&gt; command to substitute &amp;#8220;foo&amp;#8221; with &amp;#8220;bar&amp;#8221; on each line.&lt;/p&gt;
&lt;p&gt;To replace all &amp;#8220;foos&amp;#8221; with &amp;#8220;bars&amp;#8221;, add the global &lt;code&gt;/g&lt;/code&gt; flag:&lt;/p&gt;
&lt;pre&gt;perl -pe 's/foo/bar/g'&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;81. Substitute (find and replace) &amp;#8220;foo&amp;#8221; with &amp;#8220;bar&amp;#8221; on lines that match &amp;#8220;baz&amp;#8221;. &lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;perl -pe '/baz/ &amp;#038;&amp;#038; s/foo/bar/'&lt;/pre&gt;
&lt;p&gt;This one-liner is equivalent to:&lt;/p&gt;
&lt;pre&gt;
while (defined($line = &amp;lt;&amp;gt;)) {
  if ($line =~ /baz/) {
    $line =~ s/foo/bar/
  }
}
&lt;/pre&gt;
&lt;p&gt;It puts each line in variable &lt;code&gt;$line&lt;/code&gt;, then checks if line matches &amp;#8220;baz&amp;#8221;, and if it does, it replaces &amp;#8220;foo&amp;#8221; with &amp;#8220;bar&amp;#8221; in it.&lt;/p&gt;
&lt;h2&gt;Got tired.&lt;/h2&gt;
&lt;p&gt;I got tired of writing one-liners at this moment. I&amp;#8217;ll update this article the same way I did the &lt;a href="http://www.catonmat.net/blog/perl-one-liners-explained-part-three/"&gt;3rd part&lt;/a&gt; - I&amp;#8217;ll add a few new one-liners each week until the article is finished.&lt;/p&gt;
&lt;h2&gt;Have Fun!&lt;/h2&gt;
&lt;p&gt;Have fun with these one-liners for now. The next part is going to be about selective printing and deleting of certain lines.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can you think of other text conversion and substitution procedures that I did not include here?&lt;/strong&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/catonmat?a=ZepRCtiIfC8:OjQz3FLoYxQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/catonmat?d=yIl2AUoC8zA"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/catonmat?a=ZepRCtiIfC8:OjQz3FLoYxQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/catonmat?i=ZepRCtiIfC8:OjQz3FLoYxQ:F7zBnMyn0Lo"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/catonmat?a=ZepRCtiIfC8:OjQz3FLoYxQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/catonmat?i=ZepRCtiIfC8:OjQz3FLoYxQ:V_sGLiPBpWU"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/catonmat?a=ZepRCtiIfC8:OjQz3FLoYxQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/catonmat?i=ZepRCtiIfC8:OjQz3FLoYxQ:gIN9vFwOqvQ"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/catonmat/~4/ZepRCtiIfC8"&gt;</content>
    <category term="Programming base64 camelcase cr crlf find html decode html encode lc lf lowercase newline one liner one liners perl perl1line.txt replace rot13 strip substitute text uc uppercase url escape url unescape"/>
    <published>2010-02-03T09:10:56Z</published>
    <updated>2010-02-03T09:10:56Z</updated>
    <author>
      <name>Peteris Krumins</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.catonmat.net/blog/perl-one-liners-explained-part-five/</id>
  </entry>
  <entry>
    <title>More design love please...</title>
    <link rel="alternate" href="http://blogs.perl.org/users/leo_lapworth/2010/02/more-design-love-please.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">This is a follow up, or rather extension to xSawyerxs Marketing the
Entire Box (including the wrapper)

I completely agree, design is the first thing people notice about a
project. If you do not put effort into the look of your projects web page
then whether you like it or not it will have an affect on the perception
of your project (and indirectly on Perl).

If someone (my list of projects is way too large at the moment
unfortunately) has time I think there are two projects which would make a
massive difference.

  * Provide a Creative Commons licensed design(s) that anyone can use for
    a Perl project. Lots of us are not designers, so even if we'd like to
    make our projects look better we don't know how!

  * See if it is possible to get CPAN redesigned, this is already the
    home to thousands of Perl projects, so improving this will have a
    massive impact.


Many of the Apple applications websites have a similar feeling (simple
and clean), this is because they all use iWeb. Good design does not mean
lots of design. It just means a clean page, and separating content under
headings (rather than having a single page with everything just listed).</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>This is a follow up, or rather extension to xSawyerxs <a href="http://blogs.perl.org/users/sawyer_x/2010/02/marketing-the-entire-box-including-the-wrapper.html">Marketing the Entire Box (including the wrapper)</a></p>

<p>I completely agree, design is the first thing people notice about a project. If you do not put effort into the look of your projects web page then whether you like it or not it will have an affect on the perception of your project (and indirectly on Perl).</p>

<p>If someone (my list of projects is way too large at the moment unfortunately) has time I think there are two projects which would make a massive difference.</p>

<ul>
	<li>Provide a Creative Commons licensed design(s) that anyone can use for a Perl project. Lots of us are not designers, so even if we'd like to make our projects look better we don't know how!</li>
<li>See if it is possible to get CPAN redesigned, this is already the home to thousands of Perl projects, so improving this will have a massive impact.</li>
</ul>

<p><br/>
Many of the Apple applications websites have a similar feeling (simple and clean), this is because they all use iWeb. Good design does not mean lots of design. It just means a clean page, and separating content under headings (rather than having a single page with everything just listed).</p>
        
    </div>
    </content>
    <category term="perl design ironman cpan"/>
    <published>2010-02-03T08:49:59Z</published>
    <updated>2010-02-03T08:49:59Z</updated>
    <author>
      <name>Ranguard</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogs.perl.org,2010:/users/leo_lapworth//12.232</id>
  </entry>
  <entry>
    <title>SD and github</title>
    <link rel="alternate" href="http://lumberjaph.net/blog/index.php/2010/02/03/sd-and-github/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">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 --from github:sukria/Dancer

sd will check your .gitconfig to find your credentials.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><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">$ git config <span>--global</span> github.user franckcuny
$ git config <span>--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">$ git sd clone <span>--from</span> github:sukria<span>/</span>Dancer</pre></div></div>

<p>sd will check your .gitconfig to find your credentials.</p>
</div>
    </content>
    <category term="ironman github perl sd"/>
    <published>2010-02-03T09:12:45+01:00</published>
    <updated>2010-02-03T09:12:45+01:00</updated>
    <author>
      <name>franck</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://lumberjaph.net/blog/?p=605</id>
  </entry>
  <entry>
    <title>Frozen Perl Limited seats left</title>
    <link rel="alternate" href="http://blog.lib.umn.edu/leonard/perl/2010/02/frozen-perl-limited-seats-left.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">We have set a cutoff limit in ACT that will keep the number of
registrants less than or equal to the number of meals we have ordered. I
hate to do this, but it really comes down to me not wanting to tell you
that you cannot eat. If you show up, I won't charge you, but you won't
eat either.
at the time of this writing, there were still five seats left.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <div>We have set a cutoff limit in ACT that will keep the number of registrants less than or equal to the number of meals we have ordered. I hate to do this, but it really comes down to me not wanting to tell you that you cannot eat. If you show up, I won't charge you, but you won't eat either.</div><div><br/></div><div>at the time of this writing, there were still five seats left.</div><div><br/></div> 
        
    </div>
    </content>
    <category term="frozen perl 10 ironman"/>
    <published>2010-02-03T07:26:14Z</published>
    <updated>2010-02-03T07:26:14Z</updated>
    <author>
      <name>leonard</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blog.lib.umn.edu,2010:/leonard/perl//10510.216401</id>
  </entry>
  <entry>
    <title>L'importanza di perl 5.12.0</title>
    <link rel="alternate" href="http://www.cattlegrid.info/blog/2010/02/perl-e-web-framework-catalyst.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">perl 5.12.0 sta per arrivare: la 5.11.4 è infatti la prima versione di
sviluppo di perl 5.11 a seguito del code freeze che dovrebbe portare
presto ad un rilascio della prossima versione stabile dell'interprete.

Perché attendo con interesse il rilascio di perl 5.12.0? Non si tratta
(solo) di una questione di novità per quanto riguarda le feature, anche
se qualcosa d'interessante c'è (leggete i perldelta per maggiori
informazioni).

L'aspetto più importante è, tuttavia, il nuovo ciclo di svliuppo. Dopo il
rilascio di Perl 5.10.0 c'è stata un po' di "discussione" su come
dovessero essere gestite le release dell'interprete, poiché tra l'una e
l'altra in precedenza erano passati spesso periodi interminabili che
potevano dare l'impressione di uno sviluppo stagnante.

L'attuale attività mostra che lo sviluppo procede spedito, e questo
trasmette fiducia: non bisognerà aspettare altri 5 anni per una versione
stabile e migliorata di perl. Se osserviamo infatti le ultime release di
sviluppo dell'interprete:

5.11.0 - 2 Ottobre 2009
5.11.1 - 20 Ottobre 2009
5.11.2 - 20 Novembre 2009
5.11.3 - 21 Dicembre 2009
5.11.4 - 20 Gennaio 2010

notiamo che la volontà di rilasciare con cadenza mensile è stata fin'ora
rispettata.

Credo che tutto ciò sia una parte alquanto importante di ciò che oggi
viene chiamato The Perl Renaissance: avere l'impressione, supportata dai
fatti, di un linguaggio che viene attivamente sviluppato a livello sia di
librerie che di interprete è fondamentale, anche per attrarre nuovi
programmatori.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>perl 5.12.0 sta per arrivare: la 5.11.4 è infatti la prima versione di sviluppo di perl 5.11 a seguito del <em>code freeze</em> che dovrebbe portare presto ad un rilascio della prossima versione stabile dell'interprete.</p>

<p>Perché attendo con interesse il rilascio di perl 5.12.0? Non si tratta (solo) di una questione di novità per quanto riguarda le feature, anche se qualcosa d'interessante c'è (leggete i <a href="http://search.cpan.org/~rjbs/perl-5.11.4/">perldelta</a> per maggiori informazioni).</p>

<p>L'aspetto più importante è, tuttavia, il nuovo ciclo di svliuppo. Dopo il rilascio di Perl 5.10.0 c'è stata un po' di "discussione" su come dovessero essere gestite le release dell'interprete, poiché tra l'una e l'altra in precedenza erano passati spesso periodi interminabili che potevano dare l'impressione di uno sviluppo stagnante.</p>

<p>L'attuale attività mostra che lo sviluppo procede spedito, e questo trasmette fiducia: non bisognerà aspettare altri 5 anni per una versione stabile e migliorata di perl. Se osserviamo infatti le ultime release di sviluppo dell'interprete:</p>

<p>5.11.0 - 2 Ottobre 2009<br/>
5.11.1 - 20 Ottobre 2009<br/>
5.11.2 - 20 Novembre 2009<br/>
5.11.3 - 21 Dicembre 2009<br/>
5.11.4 - 20 Gennaio 2010</p>

<p>notiamo che la <a href="http://www.modernperlbooks.com/mt/2009/10/why-perl-5110-matters.html">volontà di rilasciare con cadenza mensile</a> è stata fin'ora rispettata.</p>

<p>Credo che tutto ciò sia una parte alquanto importante di ciò che oggi viene chiamato <em>The Perl Renaissance</em>: avere l'impressione, supportata dai fatti, di un linguaggio che viene attivamente sviluppato a livello sia di librerie che di interprete è fondamentale, anche per attrarre nuovi programmatori.</p>
        
    </div>
    </content>
    <category term="5.11 5.11.4 5.12 ironman italiano perl perl5 release"/>
    <published>2010-02-03T06:30:06Z</published>
    <updated>2010-02-03T06:30:06Z</updated>
    <author>
      <name>Michele Beltrame</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:www.cattlegrid.info,2010:/blog//1.213</id>
  </entry>
  <entry>
    <title>DBIC::API Update</title>
    <link rel="alternate" href="http://perl-yarg.blogspot.com/2010/02/dbicapi-update.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Be prepared, folks. The next installment of DBIC::API will be backwards
compatible breaking. This means if you were relying on the old behavior
of manipulating the stash for large swaths customization, your
customizations will no longer work. The version number will jump
significantly in case this isn't warning enough.

So far, the Changes will look something like this:

  * Merge create and update into update_or_create

  * object is much advanced now:

      * Identifier can be omitted, and data_root in the request is
        interpreted

  * Because of the above one object or several is now possible for update
    or create

  * Create and Update object validation now happens iteratively

  * Creates and Updates can be mixed inside a single bulk request

  * All modifying actions on the database occur within an all-or-nothing
    transaction

  * Much of the DBIC search parameter munging is properly moved to the
    RequestArguments Role in the form of a trigger on 'search' to
    populate 'search_parameters' and 'search_attributes' which correspond
    directly to -&gt;search($parameters, $attributes);

  * Error handling is now much more consistent, using Try::Tiny
    everywhere possible

  * Tests are now modernized and use JSON::Any

  * Extending is now explicitly done via Moose method modifiers

  * The only portion of the stash in use is to allow runtime definition
    of create/update_allows

  * list is now broken down into several steps:

      * list_munge_parameters

      * list_perform_search

      * list_format_output

      * row_format_output (which is just a passthrough per row)

There will likely be a couple of more bullet points, but as can be
plainly seen, this is a BIG update. I hope to have the tests and the
distribution ready to ship to CPAN tomorrow late in the day (it is still
sitting in my local SVK repo)

This update will bring DBIC::API to the next level in terms of using it
as a web service, with more functionality built into the core by default.

If you happen to be attending Frozen Perl 2010, I'll be giving a
presentation on Catalyst datagrids, specifically my melding of ExtJS with
DBIC::API and how dumb easy it is to hook the two together now (which
makes my work life much simpler).

Anyhow, if you are still doing lots of heavy, custom CRUD exposed via web
service, I hope this update will make it more appealing to switch to
DBIC::API to handle the more mundane parts.</div>
    </summary>
    <content type="text">Be prepared, folks. The next installment of DBIC::API will be backwards compatible &lt;span&gt;breaking&lt;/span&gt;. This means if you were relying on the old behavior of manipulating the stash for large swaths customization, your customizations will no longer work. The version number will jump significantly in case this isn't warning enough.&lt;br /&gt;&lt;br /&gt;So far, the Changes will look something like this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Merge create and update into update_or_create&lt;/li&gt;&lt;li&gt;object is much advanced now:&lt;ul&gt;&lt;li&gt;Identifier can be omitted, and data_root in the request is interpreted&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Because of the above one object or several is now possible for update or create&lt;/li&gt;&lt;li&gt;Create and Update object validation now happens iteratively&lt;/li&gt;&lt;li&gt;Creates and Updates can be mixed inside a single bulk request&lt;br /&gt;&lt;/li&gt;&lt;li&gt;All modifying actions on the database occur within an all-or-nothing transaction&lt;/li&gt;&lt;li&gt;Much of the DBIC search parameter munging is properly moved to the RequestArguments Role in the form of a trigger on 'search' to populate 'search_parameters' and 'search_attributes' which correspond directly to -&amp;gt;search($parameters, $attributes);&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Error handling is now much more consistent, using Try::Tiny everywhere possible&lt;/li&gt;&lt;li&gt;Tests are now modernized and use JSON::Any&lt;/li&gt;&lt;li&gt;Extending is now explicitly done via Moose method modifiers&lt;/li&gt;&lt;li&gt;The only portion of the stash in use is to allow runtime definition of create/update_allows&lt;/li&gt;&lt;li&gt;list is now broken down into several steps:&lt;ul&gt;&lt;li&gt;list_munge_parameters&lt;/li&gt;&lt;li&gt;list_perform_search&lt;/li&gt;&lt;li&gt;list_format_output&lt;/li&gt;&lt;li&gt;row_format_output (which is just a passthrough per row)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;There will likely be a couple of more bullet points, but as can be plainly seen, this is a &lt;span&gt;BIG&lt;/span&gt; update. I hope to have the tests and the distribution ready to ship to CPAN tomorrow late in the day (it is still sitting in my local SVK repo)&lt;br /&gt;&lt;br /&gt;This update will bring DBIC::API to the next level in terms of using it as a web service, with more functionality built into the core by default.&lt;br /&gt;&lt;br /&gt;If you happen to be attending Frozen Perl 2010, I'll be giving a presentation on Catalyst datagrids, specifically my melding of ExtJS with DBIC::API and how dumb easy it is to hook the two together now (which makes my work life much simpler).&lt;br /&gt;&lt;br /&gt;Anyhow, if you are still doing lots of heavy, custom CRUD exposed via web service, I hope this update will make it more appealing to switch to DBIC::API to handle the more mundane parts.&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <published>2010-02-03T05:11:00Z</published>
    <updated>2010-02-03T05:11:00Z</updated>
    <author>
      <name>noreply@blogger.com (NPEREZ)</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-3185710566617725438.post-3140840228162288614</id>
  </entry>
  <entry>
    <title>YAPC Europe Foundation financial reports</title>
    <link rel="alternate" href="http://perl.baczynski.com/yapc/yapc-europe-foundation-financial-reports" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">YAPC Europe Foundation is nonprofit organisation, helping with
organisations of YAPCs and Perl Workshops in Europe. They help by giving
kickstart bonuses for conferences, workshops, hackathons and provideing
payment processing.

Recently they published financial reports
http://www.yapceurope.org/finance/reports/ and cashflow diagrams for past
conferences ( http://www.yapceurope.org/finance/cashflow.html ) .

From the financial report for 2009 one canread that much of their
expenses is bank and payment processign expenses – about 100 EUR for Bank
Account Charge and 600E for payment.

If you are going to organise perl conference or other similiar event with
the help of foundation – read the cashflow diagrams carefully, to avoid
sudden shortage of cash :)

Share and Enjoy: Print Digg del.icio.us Facebook Mixx Google Bookmarks
email LinkedIn MySpace Reddit RSS Slashdot StumbleUpon
Suggest to Techmeme via Twitter Technorati Twitter Twitthis
Yahoo! Bookmarks Yahoo! Buzz

See also:

  1. YAPC::EU 2009 in Lisboa (Lisbon, Lizbona)!

  2. Nice people I met at YAPC::EU – continued

  3. Lisbon guide – taxis, traps, virtualtourist</div>
    </summary>
    <content type="html">&lt;p&gt;YAPC Europe Foundation is nonprofit organisation, helping with organisations of YAPCs and Perl Workshops in Europe.  They help by giving kickstart bonuses for conferences, workshops, hackathons and provideing payment processing.&lt;/p&gt;
&lt;p&gt;Recently t&lt;strong&gt;hey published financial reports&lt;/strong&gt;&lt;a href="http://www.yapceurope.org/finance/reports/"&gt; http://www.yapceurope.org/finance/reports/&lt;/a&gt; and &lt;strong&gt;cashflow diagrams&lt;/strong&gt; for past conferences ( &lt;a href="http://www.yapceurope.org/finance/cashflow.html"&gt;http://www.yapceurope.org/finance/cashflow.html&lt;/a&gt; ) .&lt;/p&gt;
&lt;p&gt;From the financial report for 2009 one canread that much of their expenses is bank and payment processign expenses &amp;#8211; about 100 EUR for Bank Account Charge and 600E for payment.&lt;/p&gt;
&lt;p&gt;If you are going to organise perl conference or other similiar event with the help of foundation &amp;#8211; read the cashflow diagrams carefully, to avoid sudden shortage of cash &lt;img src="http://perl.baczynski.com/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt; &lt;/p&gt;



Share and Enjoy:


	&lt;a rel="nofollow" target="_blank" href="http://www.printfriendly.com/print?url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;partner=sociable" title="Print"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/printfriendly.png" alt="Print"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://digg.com/submit?phase=2&amp;amp;url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;bodytext=YAPC%20Europe%20Foundation%20is%20nonprofit%20organisation%2C%20helping%20with%20organisations%20of%20YAPCs%20and%20Perl%20Workshops%20in%20Europe.%C2%A0%20They%20help%20by%20giving%20kickstart%20bonuses%20for%20conferences%2C%20workshops%2C%20hackathons%20and%20provideing%20payment%20processing.%0D%0A%0D%0ARecently%20they%20pub" title="Digg"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/digg.png" alt="Digg"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;notes=YAPC%20Europe%20Foundation%20is%20nonprofit%20organisation%2C%20helping%20with%20organisations%20of%20YAPCs%20and%20Perl%20Workshops%20in%20Europe.%C2%A0%20They%20help%20by%20giving%20kickstart%20bonuses%20for%20conferences%2C%20workshops%2C%20hackathons%20and%20provideing%20payment%20processing.%0D%0A%0D%0ARecently%20they%20pub" title="del.icio.us"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/delicious.png" alt="del.icio.us"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;t=YAPC%20Europe%20Foundation%20financial%20reports" title="Facebook"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/facebook.png" alt="Facebook"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.mixx.com/submit?page_url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports" title="Mixx"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/mixx.png" alt="Mixx"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;annotation=YAPC%20Europe%20Foundation%20is%20nonprofit%20organisation%2C%20helping%20with%20organisations%20of%20YAPCs%20and%20Perl%20Workshops%20in%20Europe.%C2%A0%20They%20help%20by%20giving%20kickstart%20bonuses%20for%20conferences%2C%20workshops%2C%20hackathons%20and%20provideing%20payment%20processing.%0D%0A%0D%0ARecently%20they%20pub" title="Google Bookmarks"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/googlebookmark.png" alt="Google Bookmarks"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="mailto:?subject=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;body=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports" title="email"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/email_link.png" alt="email"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&amp;amp;url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;source=Perl+Perl%2C+CPAN%2C+YAPC...+et+ceatera&amp;amp;summary=YAPC%20Europe%20Foundation%20is%20nonprofit%20organisation%2C%20helping%20with%20organisations%20of%20YAPCs%20and%20Perl%20Workshops%20in%20Europe.%C2%A0%20They%20help%20by%20giving%20kickstart%20bonuses%20for%20conferences%2C%20workshops%2C%20hackathons%20and%20provideing%20payment%20processing.%0D%0A%0D%0ARecently%20they%20pub" title="LinkedIn"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/linkedin.png" alt="LinkedIn"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.myspace.com/Modules/PostTo/Pages/?u=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;t=YAPC%20Europe%20Foundation%20financial%20reports" title="MySpace"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/myspace.png" alt="MySpace"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports" title="Reddit"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/reddit.png" alt="Reddit"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://perl.baczynski.com/feed" title="RSS"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/rss.png" alt="RSS"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://slashdot.org/bookmark.pl?title=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports" title="Slashdot"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/slashdot.png" alt="Slashdot"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;title=YAPC%20Europe%20Foundation%20financial%20reports" title="StumbleUpon"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/stumbleupon.png" alt="StumbleUpon"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://twitter.com/home/?status=tip%20@Techmeme%20http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports%20YAPC%20Europe%20Foundation%20financial%20reports" title="Suggest to Techmeme via Twitter"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/techmeme.png" alt="Suggest to Techmeme via Twitter"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports" title="Technorati"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/technorati.png" alt="Technorati"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://twitter.com/home?status=YAPC%20Europe%20Foundation%20financial%20reports%20-%20http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports" title="Twitter"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/twitter.png" alt="Twitter"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="" title="Twitthis"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/" alt="Twitthis"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://bookmarks.yahoo.com/toolbar/savebm?u=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;t=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;opener=bm&amp;amp;ei=UTF-8&amp;amp;d=YAPC%20Europe%20Foundation%20is%20nonprofit%20organisation%2C%20helping%20with%20organisations%20of%20YAPCs%20and%20Perl%20Workshops%20in%20Europe.%C2%A0%20They%20help%20by%20giving%20kickstart%20bonuses%20for%20conferences%2C%20workshops%2C%20hackathons%20and%20provideing%20payment%20processing.%0D%0A%0D%0ARecently%20they%20pub" title="Yahoo! Bookmarks"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/yahoomyweb.png" alt="Yahoo! Bookmarks"&gt;&lt;/a&gt;
	&lt;a rel="nofollow" target="_blank" href="http://buzz.yahoo.com/submit/?submitUrl=http%3A%2F%2Fperl.baczynski.com%2Fyapc%2Fyapc-europe-foundation-financial-reports&amp;amp;submitHeadline=YAPC%20Europe%20Foundation%20financial%20reports&amp;amp;submitSummary=YAPC%20Europe%20Foundation%20is%20nonprofit%20organisation%2C%20helping%20with%20organisations%20of%20YAPCs%20and%20Perl%20Workshops%20in%20Europe.%C2%A0%20They%20help%20by%20giving%20kickstart%20bonuses%20for%20conferences%2C%20workshops%2C%20hackathons%20and%20provideing%20payment%20processing.%0D%0A%0D%0ARecently%20they%20pub&amp;amp;submitCategory=science&amp;amp;submitAssetType=text" title="Yahoo! Buzz"&gt;&lt;img src="http://perl.baczynski.com/wp-content/plugins/sociable/images/yahoobuzz.png" alt="Yahoo! Buzz"&gt;&lt;/a&gt;


&lt;br/&gt;&lt;br/&gt;

&lt;p&gt;See also:&lt;ol&gt;&lt;li&gt;&lt;a href="http://perl.baczynski.com/yapc/yapceu-2009-in-lisboa-lisbon-lizbona" rel="bookmark" title="Permanent Link: YAPC::EU 2009 in Lisboa (Lisbon, Lizbona)!"&gt;YAPC::EU 2009 in Lisboa (Lisbon, Lizbona)!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://perl.baczynski.com/yapc/nice-people-met-yapceu-continued" rel="bookmark" title="Permanent Link: Nice people I met at YAPC::EU &amp;ndash; continued"&gt;Nice people I met at YAPC::EU &amp;#8211; continued&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://perl.baczynski.com/yapc/lisbon-guide-taxis-traps-virtualtourist" rel="bookmark" title="Permanent Link: Lisbon guide &amp;ndash; taxis, traps, virtualtourist"&gt;Lisbon guide &amp;#8211; taxis, traps, virtualtourist&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;</content>
    <category term="yapc"/>
    <published>2010-02-03T05:57:28+01:00</published>
    <updated>2010-02-03T05:57:28+01:00</updated>
    <author>
      <name>Lech</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://perl.baczynski.com/?p=216</id>
  </entry>
  <entry>
    <title>Sybase SQL Anywhere</title>
    <link rel="alternate" href="http://blog.cachemiss.com/articles/Sybase%20SQL%20Anywhere.pod" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I will briefly discuss setting up the development version of Sybase SQL
Anywhere (ASA) on linux (or similar) and using it with Perl.

You can download it from:

http://www.sybase.com/detail?id=1016644

Go through the install process, and make a separate user for it (e.g.
sybase-asa).

In the .bashrc for the user, add:

. /opt/sqlanywhere11/bin32/sa_config.sh 

Change to that user, and now lets create a database:

mkdir logsdbinit -t ./logs/hlaghdb.log -p 4096 -dba DBA,SQL hlaghdb.db

This sets the username to DBA and the password to SQL.

Let's make an init script. Note that you should not install the init
script to run automatically because of the obnoxious agree to license
prompt on startup, use it as just a utility for starting the database.
Edit the part at the top.

#!/bin/sh## Startup script for Sybase SQL Anywhere# # description: Sybase SQL Anywhere RDBMS System# processname: dbsrv11ASA_USER=sybase-asaASA_BIN=/opt/sqlanywhere11/bin32/DB_FILE=hlaghdb.dbSRV_NAME=ASA# Find the name of the scriptNAME=`basename $0`# For SELinux we need to use 'runuser' not 'su'if [ -x /sbin/runuser ]then        SU=runuserelse        SU=sufi# Find homeASA_HOME=`$SU $ASA_USER -c 'echo \$HOME'`start() {    ASA_START=$"Starting ${NAME} service: "    $SU $ASA_USER -c ". $ASA_BIN/sa_config.sh; $ASA_BIN/dbsrv11 -ud -n $SRV_NAME $ASA_HOME/$DB_FILE"    ret=$?     if [ $ret -eq 0 ]    then            echo "$ASA_START Success."    else            echo "$ASA_START Failed!"            exit 1    fi    echo}stop() {    echo -n $"Stopping ${NAME} service: "    pkill dbsrv11    ret=$?    if [ $ret -eq 0 ]    then            echo "Success."    else            echo "Failed!"            exit 1    fi    echo}restart() {    stop    start}case "$1" in    start)        start        ;;    stop)        stop        ;;    restart)        restart        ;;    *)        echo $"Usage: $0 {start|stop|restart}"        exit 1esacexit 0

Now install the DBD::SQLAnywhere perl driver.

Source the sa_config.sh and make a copy of the
/opt/sqlanywhere11/sdk/perl directory. Change to the directory and:

perl Makefile.PLmakesudo make install

Do not use the DBD::SQLAnywhere on CPAN, it is outdated and doesn't work.

Add /opt/sqlanywhere11/lib32 to your LD_LIBRARY_PATH, and try connecting
from DBI:

perl -MDBI -le 'my $dbh = DBI-&gt;connect(  "dbi:SQLAnywhere:ASA", "DBA", "SQL"); \  print for $dbh-&gt;selectrow_array("select 42")'

DBIx::Class support for the DBD is currently in trunk.

svn url: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/0.08/trunk/

Works with ODBC (below) as well, Schema::Loader support is coming soon.

To use with unixODBC, add the following to /etc/odbcinst.ini:

[SybASA]
Description = Sybase SQL Anywhere
Driver = /opt/sqlanywhere11/lib32/libdbodbc11.so
Setup = /opt/sqlanywhere11/lib32/libdbodbc11.so
FileUsage = 1

There are also _r versions of the drivers in that directory, these are
the threaded libraries.

Then to connect from Perl:

perl -MDBI -le 'my $dbh = DBI-&gt;connect( \  "dbi:ODBC:driver=SybASA;ENG=ASA", \  "DBA", "SQL"); \  print for $dbh-&gt;selectrow_array("select 42")'</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <div class="pod">
<p>I will briefly discuss setting up the development version of Sybase SQL Anywhere
(ASA) on linux (or similar) and using it with Perl.</p>
<p>You can download it from:</p>
<p><a href="http://www.sybase.com/detail?id=1016644">http://www.sybase.com/detail?id=1016644</a></p>
<p>Go through the install process, and make a separate user for it (e.g.
<code>sybase-asa</code>).</p>
<p>In the <code>.bashrc</code> for the user, add:</p>
<pre><span class="Normal">. /opt/sqlanywhere11/bin32/sa_config.sh </span>
</pre>
<p>Change to that user, and now lets create a database:</p>
<pre><span class="BString">mkdir</span><span class="Normal"> logs</span><span class="Normal">
</span><span class="Normal">dbinit -t ./logs/hlaghdb.log -p 4096 -dba DBA,SQL hlaghdb.db</span>
</pre>
<p>This sets the username to <code>DBA</code> and the password to <code>SQL</code>.</p>
<p>Let's make an init script. Note that you should not install the init script to
run automatically because of the obnoxious agree to license prompt on startup,
use it as just a utility for starting the database. Edit the part at the top.</p>
<pre><span class="Comment">#!/bin/sh</span><span class="Comment">
</span><span class="Comment">#</span><span class="Comment">
</span><span class="Comment"># Startup script for Sybase SQL Anywhere</span><span class="Comment">
</span><span class="Comment"># </span><span class="Comment">
</span><span class="Comment"># description: Sybase SQL Anywhere RDBMS System</span><span class="Comment">
</span><span class="Comment"># processname: dbsrv11</span>

<span class="Others">ASA_USER=</span><span class="Normal">sybase-asa</span><span class="Normal">
</span><span class="Others">ASA_BIN=</span><span class="Normal">/opt/sqlanywhere11/bin32/</span><span class="Normal">
</span><span class="Others">DB_FILE=</span><span class="Normal">hlaghdb.db</span><span class="Normal">
</span><span class="Others">SRV_NAME=</span><span class="Normal">ASA</span>

<span class="Comment"># Find the name of the script</span><span class="Comment">
</span><span class="Others">NAME=</span><span class="Keyword">`</span><span class="Normal">basename </span><span class="Others">$0</span><span class="Keyword">`</span>

<span class="Comment"># For SELinux we need to use 'runuser' not 'su'</span><span class="Comment">
</span><span class="Keyword">if</span><span class="Reserved"> [</span><span class="Normal"> -x /sbin/runuser</span><span class="Reserved"> ]</span><span class="Normal">
</span><span class="Keyword">then</span><span class="Normal">
</span><span class="Normal">        </span><span class="Others">SU=</span><span class="Normal">runuser</span><span class="Normal">
</span><span class="Keyword">else</span><span class="Normal">
</span><span class="Normal">        </span><span class="Others">SU=</span><span class="Normal">su</span><span class="Normal">
</span><span class="Keyword">fi</span>

<span class="Comment"># Find home</span><span class="Comment">
</span><span class="Others">ASA_HOME=</span><span class="Keyword">`</span><span class="Others">$SU</span><span class="Normal"> </span><span class="Others">$ASA_USER</span><span class="Normal"> -c </span><span class="String">'echo \$HOME'</span><span class="Keyword">`</span>

<span class="Char">start()</span><span class="Normal"> </span><span class="Keyword">{</span><span class="Normal">
</span><span class="Normal">    </span><span class="Others">ASA_START=</span><span class="String">$"Starting </span><span class="Others">${NAME}</span><span class="String"> service: "</span>

<span class="Normal">    </span><span class="Others">$SU</span><span class="Normal"> </span><span class="Others">$ASA_USER</span><span class="Normal"> -c </span><span class="String">". </span><span class="Others">$ASA_BIN</span><span class="String">/sa_config.sh; </span><span class="Others">$ASA_BIN</span><span class="String">/dbsrv11 -ud -n </span><span class="Others">$SRV_NAME</span><span class="String"> </span><span class="Others">$ASA_HOME</span><span class="String">/</span><span class="Others">$DB_FILE</span><span class="String">"</span>

<span class="Normal">    </span><span class="Others">ret=$?</span><span class="Normal"> </span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">if</span><span class="Reserved"> [</span><span class="Normal"> </span><span class="Others">$ret</span><span class="Normal"> -eq 0</span><span class="Reserved"> ]</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">then</span><span class="Normal">
</span><span class="Normal">            </span><span class="Reserved">echo</span><span class="Normal"> </span><span class="String">"</span><span class="Others">$ASA_START</span><span class="String"> Success."</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">else</span><span class="Normal">
</span><span class="Normal">            </span><span class="Reserved">echo</span><span class="Normal"> </span><span class="String">"</span><span class="Others">$ASA_START</span><span class="String"> Failed!"</span><span class="Normal">
</span><span class="Normal">            </span><span class="Reserved">exit</span><span class="Normal"> 1</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">fi</span><span class="Normal">
</span><span class="Normal">    </span><span class="Reserved">echo</span><span class="Normal">
</span><span class="Normal">}</span>

<span class="Char">stop()</span><span class="Normal"> </span><span class="Keyword">{</span><span class="Normal">
</span><span class="Normal">    </span><span class="Reserved">echo</span><span class="Normal"> -n </span><span class="String">$"Stopping </span><span class="Others">${NAME}</span><span class="String"> service: "</span>

<span class="Normal">    pkill dbsrv11</span>

<span class="Normal">    </span><span class="Others">ret=$?</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">if</span><span class="Reserved"> [</span><span class="Normal"> </span><span class="Others">$ret</span><span class="Normal"> -eq 0</span><span class="Reserved"> ]</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">then</span><span class="Normal">
</span><span class="Normal">            </span><span class="Reserved">echo</span><span class="Normal"> </span><span class="String">"Success."</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">else</span><span class="Normal">
</span><span class="Normal">            </span><span class="Reserved">echo</span><span class="Normal"> </span><span class="String">"Failed!"</span><span class="Normal">
</span><span class="Normal">            </span><span class="Reserved">exit</span><span class="Normal"> 1</span><span class="Normal">
</span><span class="Normal">    </span><span class="Keyword">fi</span><span class="Normal">
</span><span class="Normal">    </span><span class="Reserved">echo</span><span class="Normal">
</span><span class="Normal">}</span>

<span class="Char">restart()</span><span class="Normal"> </span><span class="Keyword">{</span><span class="Normal">
</span><span class="Normal">    stop</span><span class="Normal">
</span><span class="Normal">    start</span><span class="Normal">
</span><span class="Keyword">}</span>

<span class="Keyword">case</span><span class="Normal"> </span><span class="String">"</span><span class="Others">$1</span><span class="String">"</span><span class="Keyword"> in</span><span class="Normal">
</span><span class="Normal">    start</span><span class="Keyword">)</span><span class="Normal">
</span><span class="Normal">        start</span><span class="Normal">
</span><span class="Normal">        </span><span class="Keyword">;;</span><span class="Normal">
</span><span class="Normal">    stop</span><span class="Keyword">)</span><span class="Normal">
</span><span class="Normal">        stop</span><span class="Normal">
</span><span class="Normal">        </span><span class="Keyword">;;</span><span class="Normal">
</span><span class="Normal">    restart</span><span class="Keyword">)</span><span class="Normal">
</span><span class="Normal">        restart</span><span class="Normal">
</span><span class="Normal">        </span><span class="Keyword">;;</span><span class="Normal">
</span><span class="Normal">    *</span><span class="Keyword">)</span><span class="Normal">
</span><span class="Normal">        </span><span class="Reserved">echo</span><span class="Normal"> </span><span class="String">$"Usage: </span><span class="Others">$0</span><span class="String"> {start|stop|restart}"</span><span class="Normal">
</span><span class="Normal">        </span><span class="Reserved">exit</span><span class="Normal"> 1</span><span class="Normal">
</span><span class="Normal">esac</span><span class="Normal">
</span><span class="Reserved">exit</span><span class="Normal"> 0</span>
</pre>
<p>Now install the <code>DBD::SQLAnywhere</code> perl driver.</p>
<p>Source the <code>sa_config.sh</code> and make a copy of the <code>/opt/sqlanywhere11/sdk/perl</code>
directory. Change to the directory and:</p>
<pre><span class="BString">perl</span><span class="Normal"> Makefile.PL</span><span class="Normal">
</span><span class="BString">make</span><span class="Normal">
</span><span class="BString">sudo</span><span class="Normal"> </span><span class="BString">make</span><span class="Normal"> </span><span class="BString">install</span>
</pre>
<p>Do not use the <code>DBD::SQLAnywhere</code> on CPAN, it is outdated and doesn't work.</p>
<p>Add <code>/opt/sqlanywhere11/lib32</code> to your <code>LD_LIBRARY_PATH</code>, and try connecting
from DBI:</p>
<pre><span class="BString">perl</span><span class="Normal"> -MDBI -le </span><span class="String">'my $dbh = DBI-&gt;connect(</span><span class="String">
</span><span class="String">  "dbi:SQLAnywhere:ASA", "DBA", "SQL"); \</span><span class="String">
</span><span class="String">  print for $dbh-&gt;selectrow_array("select 42")'</span>
</pre>
<p><code>DBIx::Class</code> support for the DBD is currently in trunk.</p>
<p>svn url: <a href="http://dev.catalyst.perl.org/repos/bast/DBIx-Class/0.08/trunk/">http://dev.catalyst.perl.org/repos/bast/DBIx-Class/0.08/trunk/</a></p>
<p>Works with ODBC (below) as well, <code>Schema::Loader</code> support is coming soon.</p>
<p>To use with unixODBC, add the following to <code>/etc/odbcinst.ini</code>:</p>
<pre>[SybASA]
Description = Sybase SQL Anywhere
Driver = /opt/sqlanywhere11/lib32/libdbodbc11.so
Setup = /opt/sqlanywhere11/lib32/libdbodbc11.so
FileUsage = 1
</pre>
<p>There are also <code>_r</code> versions of the drivers in that directory, these are the
threaded libraries.</p>
<p>Then to connect from Perl:</p>
<pre><span class="BString">perl</span><span class="Normal"> -MDBI -le </span><span class="String">'my $dbh = DBI-&gt;connect( \</span><span class="String">
</span><span class="String">  "dbi:ODBC:driver=SybASA;ENG=ASA", \</span><span class="String">
</span><span class="String">  "DBA", "SQL"); \</span><span class="String">
</span><span class="String">  print for $dbh-&gt;selectrow_array("select 42")'</span>
</pre>


</div>
      </div>
    </content>
    <published>2010-02-03T04:24:57Z</published>
    <updated>2010-02-03T04:24:57Z</updated>
    <author>
      <name>Rafael Kitover</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:urn:guid:9400932A-1062-11DF-B0D5-590369D39F9F</id>
  </entry>
  <entry>
    <title>DBIx::Class::Schema::Loader 0.05000</title>
    <link rel="alternate" href="http://blog.cachemiss.com/articles/DBIx%3A%3AClass%3A%3ASchema%3A%3ALoader%200.05000.pod" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">DBIx::Class::Schema::Loader current, more than a year in the making, is
finally out in an official release:

http://search.cpan.org/~rkitover/DBIx-Class-Schema-Loader-0.05000/lib/DBIx/Class/Schema/Loader.pm

It:

  * makes nicer relationship names

  * singularizes class names for tables

  * supports more databases (MSSQL and Sybase ASE)

  * generates more accurate column data, moreso for some of the backends
    like Pg and Sybase than others, but still more accurate for all
    backends than 0.04006.

  * uses might_have instead of has_many for FKs to a unique constraint

  * generates POD also incorporating COMMENT metadata for Pg

  * has full backward compatibility and upgrade/downgrade code

  * various improvements for the backends

  * conversion of the repo to git thanks to ilmari (doing the conversion)
    and nothingmuch (for git-svn-abandon). The new repo is at:

    http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class-Schema-Loader.git;a=summary

Some of the things on the TODO list for later in the 0.05 series:

  * accurate data_type/size/default_value for all backends (currently
    true for Pg and Sybase.)

    This should allow schemas to round trip through SQLT -&gt;deploy.

  * options for timezone and locale, for better InflateColumn::DateTime
    support (which will be available through the Catalyst helper.)

  * introspecting COMMENT metadata for POD for backends other than Pg

  * Sybase SQL Anywhere (ASA) support, possibly other new backends
    (Informix, Firebird ...)

  * making ::View classes for views with the defining SQL so they can be
    properly deployed

  * going through the huge RT queue

  * optimizing things (dumping e.g. a large mssql schema can take hours I
    hear.)

  * lots of other misc. crap (like refactoring my horrible backcompat
    tests.)

Longer term, we'd like to eventually merge some of the functionality of
the new SQL::Translator Justin Hunter (arcanez) is working on with the
loader (and vice-versa.)

The Catalyst tutorial should be updated soon to make use of the new
Loader and SQLite foreign keys (though the current version will work just
fine.)</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <div class="pod">
<p>DBIx::Class::Schema::Loader current, more than a year in the making, is finally
out in an official release:</p>
<p><a href="http://search.cpan.org/~rkitover/DBIx-Class-Schema-Loader-0.05000/lib/DBIx/Class/Schema/Loader.pm">http://search.cpan.org/~rkitover/DBIx-Class-Schema-Loader-0.05000/lib/DBIx/Class/Schema/Loader.pm</a></p>
<p>It:</p>
<ul>
		<li>makes nicer relationship names	</li>
		<li>singularizes class names for tables	</li>
		<li>supports more databases (MSSQL and Sybase ASE)	</li>
		<li>generates more accurate column data, moreso for some of the backends like Pg and
Sybase than others, but still more accurate for all backends than <code>0.04006</code>.	</li>
		<li>uses <code>might_have</code> instead of <code>has_many</code> for FKs
to a unique constraint	</li>
		<li>generates POD also incorporating <code>COMMENT</code> metadata for Pg	</li>
		<li>has full backward compatibility and upgrade/downgrade code	</li>
		<li>various improvements for the backends	</li>
		<li>conversion of the repo to git thanks to ilmari (doing the conversion) and
nothingmuch (for git-svn-abandon). The new repo is at:
<br/><br/><a href="http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class-Schema-Loader.git;a=summary">http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class-Schema-Loader.git;a=summary</a></li>
</ul>

<p>Some of the things on the TODO list for later in the <code>0.05</code> series:</p>
<ul>
		<li>accurate data_type/size/default_value for all backends (currently true for Pg
and Sybase.)
<br/><br/>This should allow schemas to round trip through SQLT <code>-&gt;deploy</code>.	</li>
		<li>options for timezone and locale, for better <code>InflateColumn::DateTime</code> support
(which will be available through the Catalyst helper.)	</li>
		<li>introspecting <code>COMMENT</code> metadata for POD for backends other than Pg	</li>
		<li>Sybase SQL Anywhere (ASA) support, possibly other new backends (Informix,
Firebird ...)	</li>
		<li>making <code>::View</code> classes for views with the defining SQL so they can be properly
deployed	</li>
		<li>going through the huge RT queue	</li>
		<li>optimizing things (dumping e.g. a large mssql schema can take hours I hear.)	</li>
		<li>lots of other misc. crap (like refactoring my horrible backcompat tests.)</li>
</ul>

<p>Longer term, we'd like to eventually merge some of the functionality of the new
<code>SQL::Translator</code> Justin Hunter (arcanez) is working on with the loader (and
vice-versa.)</p>
<p>The Catalyst tutorial should be updated soon to make use of the new Loader and
SQLite foreign keys (though the current version will work just fine.)</p>


</div>
      </div>
    </content>
    <published>2010-02-03T00:36:22Z</published>
    <updated>2010-02-03T00:36:22Z</updated>
    <author>
      <name>Rafael Kitover</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:urn:guid:DF6B8FEC-105B-11DF-ABF9-5A0369D39F9F</id>
  </entry>
  <entry>
    <title>Состоялся второй болгарский Perl-воркшоп</title>
    <link rel="alternate" href="http://onperl.ru/onperl/2010/02/sostojalsja-vtoroj-bolgarskij-perl-vorkshop.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">30 января в Софии прошел второй болгарский Perl-воркшоп. Первое
мероприятие было проведено ровно год назад, 31 января 2009 года.

На этот раз посетителей и докладов было поменьше, но сам воркшоп от этого
ничуть не пострадал. (Хотя, надо вспомнить офлайн № 17 Moscow.pm,
размывший понятия воркшопа и встречи pm-группы.)

Воркшоп помогали организовывать Бойчо Бойчев и Мариан Маринов, который
регулярно проводит конференцию по открытому ПО OpenFest, приезжал в
Москву рассказывать про Gluster, и возил Джонатана смотреть окрестности
Софии.

Выступлений было три, но все они получились продолжительными :-) Мариан
рассказал про AnyEvent, Петар Шангов — про Catalyst, я — про Gearman.

На социальную часть людей пришло чуть ли не больше, чем на основную.
Выяснилось, что случился локальный эпик фейл с анонсом. Каждую последнюю
пятницу месяца в Софии проходит какое-либо IT-мероприятие, и обычно оно
начинается в 13 часов. На одном из местных линуксовых сайтов анонс
воркшопа висел под статической шапкой, где и было указано это время, хотя
наше мероприятие началось в 11. На шапку посмотрели, а текст анонса не
почитали.

Интересная деталь: среди участников (по крайней мере, социальной части
:-) были отец и сын. Два поколения, старший — Пламен и младший — Николай.
Отец, к тому же, говорил по-русски и много рассказал про Софию, про
скользкие желтые кирпичи на центральной — «Желтой» — площади, про бывший
проспект Ленина и нынешний Царя-освободителя, а заодно про македонцев,
ментлитет итальянцев, англицизмы и русизмы в болгарском языке.

На следующий год мы планируем провести третье мероприятие про Perl в
Болгарии, но сделаем это вместе с одним из регулярных IT-мероприятий в
Софии.</div>
    </summary>
    <content type="html">
        &lt;p&gt;30 января в Софии прошел &lt;a href="http://event.perlbulgaria.org/sofia2010/"&gt;второй болгарский Perl-воркшоп&lt;/a&gt;. Первое мероприятие было проведено ровно год назад, 31 января 2009 года.&lt;/p&gt;
&lt;p&gt;На&amp;nbsp;этот раз посетителей и докладов было поменьше, но сам воркшоп от этого ничуть не пострадал. (Хотя,&amp;nbsp;надо вспомнить &lt;a href="http://moscow.pm.org/tuan2hmnm41cianwu17r"&gt;офлайн № 17 Moscow.pm&lt;/a&gt;, размывший понятия воркшопа и встречи pm-группы.)&lt;/p&gt;
&lt;p&gt;Воркшоп помогали организовывать&amp;nbsp;&lt;font color="#000000" size="2" face="Arial"&gt;Бойчо Бойчев и &lt;/font&gt;&lt;a href="http://event.perlbulgaria.org/sofia2010/user/3491"&gt;Мариан Маринов&lt;/a&gt;, который регулярно проводит конференцию по открытому ПО &lt;a href="http://openfest.org/"&gt;OpenFest&lt;/a&gt;, приезжал в Москву &lt;a href="http://highload.ru/papers2008/7163.html"&gt;рассказывать про Gluster&lt;/a&gt;, и возил Джонатана &lt;a href="http://jnthn.net/cgi-bin/photos.pl?albumid=41"&gt;смотреть окрестности Софии&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Выступлений было три, но все они получились продолжительными :-) Мариан рассказал про AnyEvent, &lt;a href="http://mechanicalrevolution.com/"&gt;Петар Шангов&lt;/a&gt; — про Catalyst, я — про &lt;a href="http://onperl.ru/onperl/2010/02/gearman-5-prezentacija.html"&gt;Gearman&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;На социальную часть людей пришло чуть ли не больше, чем на основную. Выяснилось, что случился локальный эпик фейл с анонсом. Каждую последнюю пятницу месяца в Софии проходит какое-либо IT-мероприятие, и обычно оно начинается в 13 часов. На одном из местных линуксовых сайтов &lt;a href="http://img.onperl.ru/techcamp.gif"&gt;анонс воркшопа висел&lt;/a&gt; под статической шапкой, где и было указано это время, хотя наше мероприятие началось в 11. На шапку посмотрели, а текст анонса не почитали.&lt;/p&gt;
&lt;p&gt;Интересная деталь: среди участников (по крайней мере, социальной части :-) были отец и сын. Два поколения,&amp;nbsp;старший&amp;nbsp;— Пламен и младший — Николай. Отец, к тому же, говорил по-русски и много рассказал про Софию, про скользкие желтые кирпичи на центральной — «Желтой» —&amp;nbsp;площади, про бывший проспект Ленина и нынешний Царя-освободителя, а заодно про македонцев, ментлитет итальянцев, англицизмы и русизмы в болгарском языке.&lt;/p&gt;
&lt;p&gt;На следующий год мы планируем провести третье мероприятие про Perl в Болгарии, но сделаем это вместе с одним из регулярных IT-мероприятий в Софии.&lt;/p&gt;
        
    </content>
    <category term="Мероприятия Сообщество bulgaria event perl workshop"/>
    <published>2010-02-02T21:48:50+01:00</published>
    <updated>2010-02-02T21:48:50+01:00</updated>
    <author>
      <name>ash</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:onperl.ru,2010:/onperl//1.128</id>
  </entry>
  <entry>
    <title>Catalyst, nginx and FastCGI &amp;#8211; my first bloody nose</title>
    <link rel="alternate" href="http://richard.wallman.org.uk/2010/02/catalyst-nginx-and-fastcgi-my-first-bloody-nose/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Always a glutton for punishment, a recent project to redevelop a website involved changing pretty much every layer of the stack – Apache became nginx, mod_perl became FastCGI, and the custom code was moved into a Catalyst project. Having never seriously worked with any of these before, my first deployment (today!) was an interesting affair.
Note: [...]</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Always a glutton for punishment, a recent project to redevelop a website involved changing pretty much every layer of the stack – Apache became nginx, mod_perl became FastCGI, and the custom code was moved into a Catalyst project. Having never seriously worked with any of these before, my first deployment (today!) was an interesting affair.
Note: [...]</div>
    </content>
    <category term="Miscellaneous catalyst fastcgi nginx perl"/>
    <published>0</published>
    <updated>0</updated>
    <author>
      <name>richard</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://richard.wallman.org.uk/?p=106</id>
  </entry>
  <entry>
    <title>Dive into Dancer&amp;#8217;s code: core and extensions</title>
    <link rel="alternate" href="http://www.sukria.net/fr/archives/2010/02/02/dive-into-dancers-code-core-and-extensions/" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">The discussion that is rising these days about frameworks and libraries
reminds me I did not even take the time to talk about the last version of
Dancer.
I should have, hence this post.

Last version of Dancer, 1.130, is the first version which is
"plugin-aware".
That means since 1.130 anyone can write their own template, logger or
session engine and rock the app by just setting the appropriate value to
the corresponding setting.

The plugins that existed before the split have been extracted from the
core distribution in order to be shipped separately, that's much clean
and makes more sense that way:

  * Dancer : the core framework, plus essential plugins

  * Dancer::Logger::LogHandler : logger engine for Log::Handler (written
    by Frank Cuny)

  * Dancer::Template::MicroTemplate : template engine for
    Text::MicroTemplate (written by Frank Cuny)

  * Dancer::Session::Cookie : session engine based on encrypted cookie
    (written by Алексей Капранов)

  * Dancer::Session::Memcached : session engine based on memcached

If you have a template, logger or session engine you'd like to see in
Dancer's ecosystem, I invite you to take a look at the corresponding
interfaces you have to implement, it's pretty straight forward.

The concept is pretty easy, basically, here are the steps to follow to
add a new engine:

  * choose a setting name that is available for template, session or
    logger, according to what you're doing.

  * implement the interface of the engine you like
    (Dancer::Template::Abstract, Dancer::Session::Abstract,
    Dancer::Logger::Abstract)

  * Name your class with a camelized version of the setting name

Here is an example, let's say you have a great template engine you'd love
to use for rendering your views in your Dancer app, let's name it
"HTML::IronMark".

  * First of all, create Dancer::Template::Ironmark which implements the
    interface Dancer::Template::Abstract

  * Then change the setting template to "ironmark"

And well, you're done. This is pretty much the same job for logger and
session engines.

Feel free to contact me if you want to write your own and need more
precisions.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>The discussion that is rising these days about <a href="http://stevan-little.blogspot.com/2010/02/on-frameworks.html">frameworks</a> and <a href="http://perlalchemy.blogspot.com/2010/02/frameworks-are-framing-libraries-are.html">libraries</a> reminds me I did not even take the time to talk about the last version of <a href="http://dancer.sukria.net">Dancer</a>.<br/>
I should have, hence this post.</p>
<p>Last version of Dancer, <a href="http://search.cpan.org/~sukria/Dancer-1.130/">1.130</a>, is the first version which is "plugin-aware".<br/>
That means since 1.130 anyone can write their own template, logger or session engine and rock the app by just setting the appropriate value to the corresponding setting.</p>
<p>The plugins that existed before the split have been extracted from the core distribution in order to be shipped separately, that's much clean and makes more sense that way:</p>
<ul>
<li><a href="http://search.cpan.org/dist/Dancer/">Dancer</a> : the core framework, plus essential plugins</li>
<li><a href="http://search.cpan.org/dist/Dancer-Logger-LogHandler/">Dancer::Logger::LogHandler</a> : logger engine for <a href="http://search.cpan.org/dist/Log-Handler/">Log::Handler</a> (written by <a href="http://search.cpan.org/~franckc/">Frank Cuny</a>)</li>
<li><a href="http://search.cpan.org/dist/Dancer-Template-MicroTemplate/">Dancer::Template::MicroTemplate</a> : template engine for <a href="http://search.cpan.org/dist/Text-MicroTemplate/">Text::MicroTemplate</a> (written by <a href="http://search.cpan.org/~franckc/">Frank Cuny</a>)</li>
<li><a href="http://search.cpan.org/dist/Dancer-Session-Cookie/">Dancer::Session::Cookie</a> : session engine based on encrypted cookie (written by <a href="http://search.cpan.org/~kappa/">Алексей Капранов</a>)</li>
<li><a href="http://search.cpan.org/dist/Dancer-Session-Memcached/">Dancer::Session::Memcached</a> : session engine based on memcached</li>
</ul>
<p>If you have a template, logger or session engine you'd like to see in Dancer's ecosystem, I invite you to take a look at the corresponding interfaces you have to implement, it's pretty straight forward.</p>
<p>The concept is pretty easy, basically, here are the steps to follow to add a new engine:</p>
<ul>
<li>choose a setting name that is available for <code>template</code>, <code>session</code> or <code>logger</code>, according to what you're doing.
</li>
<li>implement the interface of the engine you like (Dancer::Template::Abstract, Dancer::Session::Abstract, Dancer::Logger::Abstract)</li>
<li>Name your class with a camelized version of the setting name</li>
</ul>
<p>Here is an example, let's say you have a great template engine you'd love to use for rendering your views in your Dancer app, let's name it "HTML::IronMark".</p>
<ul>
<li>First of all, create Dancer::Template::Ironmark which implements the interface <a href="http://search.cpan.org/~sukria/Dancer-1.130/lib/Dancer/Template/Abstract.pm">Dancer::Template::Abstract</a></li>
<li>Then change the setting <code>template</code> to <code>"ironmark"</code></li>
</ul>
<p>And well, you're done. This is pretty much the same job for logger and session engines.</p>
<p>Feel free to <a href="http://dancer.sukria.net/about">contact me</a> if you want to write your own and need more precisions.</p>
</div>
    </content>
    <category term="Programming Dancer Perl"/>
    <published>2010-02-02T20:15:33+01:00</published>
    <updated>2010-02-02T20:15:33+01:00</updated>
    <author>
      <name>sukria</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://www.sukria.net/fr/?p=1407</id>
  </entry>
  <entry>
    <title>Showing Perl on non-Perl conferences, getting money from TPF for swag</title>
    <link rel="alternate" href="http://szabgab.com/blog/2010/02/1265137032.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">On this weekend I'll be on FOSDEM along with several other Perl Mongers.
In addition to just trying to enjoy the talks we'll be promoting Perl. I
am really happy that The Perl Foundation was ready to provide us with
$500 to buy conference swag we can give away.

Similarry, a month from now we will be present at CeBIT in Hannover,
Germany where we will have a booth to promote Perl and Perl based
projects. I've just heard from Karen Pauley that TPF agreed to provide us
another $500 for further materials to give away on CeBIT.

This is awesome and this probably means that if you are ready to talk to
people on non-perl related events telling them about Perl you could also
get some money from TPF in order to have some hard material to give away.

For FOSDEM we are preparing some round tuits and a postcard listing the
Perl events in Europe that will take place in the coming months.

For CeBIT we are also preparing some further marketing materials - more
business oriented - that we will be able to hand out.

There are further ideas to prepare various fun promotional materials one
can give away during a chat with a fellow developer and we have also
discussed that we should have a Linux liveCD full of Perl applications
ready to be used by anyone. (Also include Windows binaries in the form of
Strawberry Perl for those using Windows)

Of course almost none of the the above is my work. There are several
people involved in the preparation: Rich Sands organzied the tuits and
the postcards for FOSDEM, Salve J. Nilsen is working and on community
intro cards, Renee Backer is working hard on the materials for CeBIT just
to thank a few of them.

We are also expecting some help from the Enlightend Perl Organization
(EPO) as they are preparing beer-mats to give away.


Getting involved
----------------

Most of the conversation about this is done on the events mailing list
and some data is collected on the TPF wiki. If you would like to help in
preparing the materials or if you'd are planning to attend a non-perl
event and would like to have some fun or business oriented material to
give away, please join us on the events mailing list to discuss the
details. You can find information on the TPF wiki.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><p>
On this weekend I'll be on <a href="http://www.fosdem.org/">FOSDEM</a> along with several other Perl Mongers. 
In addition to just trying to enjoy the talks we'll be promoting Perl. I am really happy that 
<a href="http://www.perlfoundation.org/">The Perl Foundation</a> was ready to provide us with $500
to buy conference swag we can give away.
</p>
<p>
Similarry, a month from now we will be present at <a href="http://www.cebit.de/">CeBIT</a> in Hannover,
Germany where we will have a booth to promote Perl and Perl based projects. I've just heard from 
<a href="http://martian.org/karen/">Karen Pauley</a> that TPF agreed to provide us another $500 
for further materials to give away on CeBIT.
</p>
<p>
This is awesome and this probably means that if you are ready to talk to people on non-perl related
events telling them about Perl <b>you could also get some money from TPF</b> in order to have some hard
material to give away.
</p>
<p>
For FOSDEM we are preparing some <a href="http://www.flickr.com/photos/hfb/56871343/">round tuits</a>
and a postcard listing the Perl events in Europe that will take place in the coming months.
</p>
<p>
For CeBIT we are also preparing some further marketing materials - more business oriented - that we will
be able to hand out.
</p>
<p>
There are further ideas to prepare various fun promotional materials one can give away during a chat with
a fellow developer and we have also discussed that we should have a Linux liveCD full of Perl applications
ready to be used by anyone. (Also include Windows binaries in the form of Strawberry Perl for those using Windows)
</p>
<p>
Of course almost none of the the above is my work. There are several people involved in the preparation:
<a href="http://www.RSandsConsulting.com">Rich Sands</a> organzied the tuits and the postcards for FOSDEM,
<a href="http://use.perl.org/~sjn/journal/">Salve J. Nilsen</a> is working and on community intro cards,
<a href="http://reneeb-perlblog.blogspot.com/">Renee Backer</a> is working hard on the materials for CeBIT
just to thank a few of them.
</p>
<p>
We are also expecting some help from the <a href="http://www.enlightenedperl.org/">Enlightend Perl Organization (EPO)</a>
as they are preparing beer-mats to give away.
</p>
<p>
<h2>Getting involved</h2>
</p>
<p>
Most of the conversation about this is done on the events mailing list and some data is collected on the TPF wiki. 
If you would like to help in preparing the materials or if you'd are planning to attend a non-perl event and would
like to have some fun or business oriented material to give away, please join us on the events mailing list
to discuss the details.  You can find information on the <a href="http://www.perlfoundation.org/perl5/index.cgi?events">TPF wiki</a>.
</p>
</div>
    </content>
    <category term="Perl, FOSDEM, CeBIT, TPF, EPO, conferences, marketing"/>
    <published>2010-02-02T10:57:12Z</published>
    <updated>2010-02-02T10:57:12Z</updated>
    <author>
      <name>Gabor Szabo</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://szabgab.com/blog/2010/02/1265137032.html</id>
  </entry>
  <entry>
    <title>Cultured Perl Blog</title>
    <link rel="alternate" href="http://perlhacks.com/2010/02/cultured-perl-blog.php" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"> A couple of years ago I thought that one thing the Perl community was
missing was a network of blog sites about Perl. I'm not talking about the
individual blogs that are being shown off to such good effect by the Iron
Man project, I'm talking about a set of multi-author blogs that covered
particular facets of the Perl world. Something like a Perl-specific
version of LifeHacker or BoingBoing. To that end, I registered a number
of domains and set about installing Movable Type.

That bit was easy. That bit I can do. The next bit is harder.

The next bit involves getting authors interested in writing for the blogs
on a regular basis. That bit I didn't do so well at and none of the blogs
florished.

One of them didn't even get going. That was Cultured Perl. The idea
behind Cultured Perl was that it would discuss Perl culture. That's all
the non-technical bits of the Perl world. Perl Mongers, Perl conferences,
things like that. I had a few authors signed up, but nothing ever really
happened.

So why am I telling you this? Well, the Cultured Perl domains are up for
renewal. And I'm trying to work out whether it's worth keeping them.

Would you be interested in reading a Cultured Perl blog? And would you be
interested in writing for it?</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
            A couple of years ago I thought that one thing the Perl community was missing was a network of blog sites about Perl. I'm not talking about the individual blogs that are being shown off to such good effect by the <a href="http://ironman.enlightenedperl.org/">Iron Man project</a>, I'm talking about a set of multi-author blogs that covered particular facets of the Perl world. Something like a Perl-specific version of <a href="http://lifehacker.com/">LifeHacker</a> or <a href="http://boingboing.net/">BoingBoing</a>. To that end, I registered a number of domains and set about installing Movable Type.<br/><br/>That bit was easy. That bit I can do. The next bit is harder.<br/><br/>The next bit involves getting authors interested in writing for the blogs on a regular basis. That bit I didn't do so well at and none of the blogs florished.<br/><br/>One of them didn't even get going. That was <a href="http://culturedperl.com/">Cultured Perl</a>. The idea behind Cultured Perl was that it would discuss Perl culture. That's all the non-technical bits of the Perl world. Perl Mongers, Perl conferences, things like that. I had a few authors signed up, but nothing ever really happened.<br/><br/>So why am I telling you this? Well, the Cultured Perl domains are up for renewal. And I'm trying to work out whether it's worth keeping them.<br/><br/>Would you be interested in reading a Cultured Perl blog? And would you be interested in writing for it?<br/>
            
        </div>
    </content>
    <category term="Community blog community perl culture"/>
    <published>2010-02-02T10:29:46+01:00</published>
    <updated>2010-02-02T10:29:46+01:00</updated>
    <author>
      <name>Dave Cross</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:perlhacks.com,2010://1.46</id>
  </entry>
  <entry>
    <title>How To enable perl5.10 by default with MacPorts</title>
    <link rel="alternate" href="http://blog.cyberion.net/2010/02/how-to-enable-perl510-by-default-with-macports.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">$ port uninstall perl5.8
---&gt;  Unable to uninstall perl5.8 5.8.9_3, the following ports depend on it:
---&gt;    perl5

So, you should type:

$ port -f uninstall perl5.8 
---&gt;  Unable to uninstall perl5.8 5.8.9_3, the following ports depend on it:
---&gt;    perl5
Warning: Uninstall forced.  Proceeding despite dependencies.
---&gt;  Deactivating perl5.8 @5.8.9_3
---&gt;  Uninstalling perl5.8 @5.8.9_3

and finally:

$ port install perl5 +perl5_10
...

which gives:

$ perl -v | grep built
This is perl, v5.10.1 (*) built for darwin-multi-2level</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml"><pre>
$ port uninstall perl5.8
---&gt;  Unable to uninstall perl5.8 5.8.9_3, the following ports depend on it:
---&gt;    perl5
</pre>

So, you should type:

<pre>
$ port -f uninstall perl5.8 
---&gt;  Unable to uninstall perl5.8 5.8.9_3, the following ports depend on it:
---&gt;    perl5
Warning: Uninstall forced.  Proceeding despite dependencies.
---&gt;  Deactivating perl5.8 @5.8.9_3
---&gt;  Uninstalling perl5.8 @5.8.9_3
</pre>

and finally:

<pre>
$ port install perl5 +perl5_10
...
</pre>

which gives:

<pre>
$ perl -v | grep built
This is perl, v5.10.1 (*) built for darwin-multi-2level
</pre></div>
    </content>
    <category term="apple, mac perl"/>
    <published>2010-02-02T06:45:59Z</published>
    <updated>2010-02-02T06:45:59Z</updated>
    <author>
      <name>Yann</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:typepad.com,2003:post-6a00d83454251869e2012877490240970c</id>
  </entry>
  <entry>
    <title>[Perl]XS基礎文法最速マスター</title>
    <link rel="alternate" href="http://d.hatena.ne.jp/gfx/20100202/1265091606" type="text/html"/>
    <summary type="text">元ネタ：Perl基礎文法最速マスター(id:perlcodesample)

XSを始めるための手順といくつかの要素の解説です。C言語をある程度知っている人でも，これを読んだだけでXSの基礎をマスターしてXSを書くことができるようにはなっていません。リファレンスでもありません。

XSとは，狭義ではPerlでエクステンションを書くためのマクロ言語の名前ですが，広義ではエクステンションを書くための技術の総称です。ここでは，広義のXSを俯瞰します。

XSはいろいろと特殊なのでテンプレは無視で行きます。

目次：

  1.  h2xsで空のディストリビューションを作る

  2.  XSファイルの構成

  3.  スレッドコンテキスト

  4.  SVファミリ

  5.  GCとスコープ

  6.  さらなる学習のために

h2xsで空のディストリビューションを作る

以下のコマンドで空のXSディストリビューションを作ることができます。

h2xs -A -b 5.8.1 -n Foo::Bar

ディストリビューションを作るためのモジュールはModule::Starter,
Module::Setupなどもありますが，最初はh2xsで十分でしょう。なによりインストールの必要がありません。

ディストリビューションを作ったら，その中のディレクトリに移動してとりあえずビルドしてみます。

cd Foo-Bar
perl Makefile.PL
make &amp;&amp; make test

これがうまくいかなければコンパイラをセットアップする必要がありますが，省略します。WindowsならStrawberry
PerlやCygwinを使うのがお勧めです。

次の節に進む前に，XSファイルの先頭，Perlのヘッダファイルをインクルードする前に，"#define PERL_NO_GET_CONTEXT"という行を追加しておきましょう。これはスレッドコンテキストと関係があるのですが，とりあえずオマジナイと考えてかまいません。また，XSセクションには"PROTOTYPES:
DISABLE"という行を加えておきましょう。この行がないとXSUBに自動的にプロトタイプがついてしまい，予想外の挙動を招くことになります。

XSファイルの構成

一つのXSファイルはCセクションとXSセクションに分かれています。CセクションはC言語そのもので，モジュールのユーザーからは見えません。XSセクションでXSUBを書き，これはモジュールのユーザーから見えます。

たとえば，以下のようになります。

#define PERL_NO_GET_CONTEXT#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "ppport.h"
=pod

C section

=cut
MODULE = Foo::Bar             PACKAGE = Foo::Bar     
PROTOTYPES: DISABLE       

=pod

XS section

=cut
voidhello()CODE:
{
    PerlIO_stdoutf("Hello, world!\n");
}

これは，以下のコマンドで実行できます。

make
perl -Mblib -MFoo::Bar -e 'Foo::Bar::hello()'

なお，上の例が示すように，セクションにかかわらず任意の場所にPODを書くことができます*1。

スレッドコンテキスト

Cセクションにいろいろ書くつもりがなければ，この節の内容は特に必要ありません。

スレッドコンテキストとは，Perlインタプリタレベルでのグローバル変数を持っている構造体で，ほとんどすべてのPerlAPIの最初の引数として渡すものです。ただし，ほとんどすべてのPerlAPIは，このことを意識しなくてすむようにマクロでラップしてあります。

このことを意識しなければならないのは，Cセクションに関数を書くときです。

このとき，自分の関数についても，PerlAPI
と同じように最初の引数にスレッドコンテキスト渡すようにしないと，その関数の内部でPerlAPIが使えません。

スレッドコンテキストの宣言にはpTHX*2/pTHX_*3を使います。API の呼出には aTHX/aTHX_ を使います。

/* in C section */static voidhello(pTHX) {
    PerlIO_stdoutf("Hello, world!\n");
}
/* IV: Integer Value */static voidincrement(pTHX_ SV* const sv) {
    sv_inc(sv); /* 実際には Perl_sv_inc(aTHX_ sv) に展開される */}
MODULE = Foo::Bar             PACKAGE = Foo::Bar     
voidhello()CODE:
{
    hello(aTHX);
}
voidincrement(SV* sv)CODE:
{
    increment(aTHX_ sv);
}

特定のプロトタイプが必要なコールバックなどではスレッドコンテキストを受け取れないことがありますが，その場合は関数の最初で dTHX;
宣言をすることにより，スレッドコンテキストを定義することができます。

SVファミリ

Perlのデータは，CレベルではSV*(スカラー)，AV*(配列)，HV*(ハッシュ)などで表現されますが，これらすべてはSV*の派生クラスと考えられます。つまり，SvTYPE()
や SvREFCNT_inc()/SvREFCNT_dec()
などのAPIは，その引数としてどのSVファミリでも受け取れるようになっています。以後，単にSVと書くときは，SVファミリのことと考えてください。

SVファミリを操作するためのAPIの数は多いので紹介はしませんが，一般に，スカラー値であれば sv_*4/Sv*5
というプレフィクスを持ち，同様に配列では av_/Av，ハッシュでは hv_/Hv
というプレフィクスを持つので，ソースコードを読むときには頭に入れておくといいでしょう。

なお，SVファミリの具体的な挙動については，perldoc perlapiを参照してください。

GCとスコープ

Perlはリファレンスカウントベースのガベージコレクション機構を持っています。また，スコープと揮発性(mortality)という概念で，XSレベルでもリファレンスカウントの管理を自動化できるようになっています。

XSにおけるスコープは，Perlレベルでのスコープと同じです。これは，ENTER; SAVETMPS; というマクロで開き，FREETMPS;
LEAVE; というマクロで閉じます*6。

そして，このスコープの中であるSVを揮発性にすると，そのSVのリファレンスカウントは，そのスコープを抜けるときに一つ減ります*7。この処理はスコープの中で例外が起きたときでもきちんと行われるので，手動でリファレンスカウントを減らすよりも安全です。SVを揮発性にするには，sv_2mortal()を使います。初めから揮発性のSVがほしいときは，sv_newmortal()が，SVの揮発性コピーがほしいときはsv_mortalcopy()を使います。

/* in C section */static voidfoo(pTHX) {
    SV* sv;
    ENTER;
    SAVETMPS;

    sv = sv_newmortal();
    sv_setpvs(sv, "Hello, world!\n");
    PerlIO_stdoutf("%"SVf, sv); /* -&gt; "Hello, world!" */
    FREETMPS;
    LEAVE;
    /* ここでsvはすでに解放されている */}

SvREFCNT_inc()とSvREFCNT_dec()でリファレンスカウントを手動で操作することもできますが，慣れないうちは手動で操作する代わりにsv_mortalcopy()とスコープメカニズムを使ったほうが安全です。

なお，すべてのXSUBは呼び出されるときにスコープで囲まれます。また，XSUBからの戻り値は揮発性のSVでなければならないという呼出規約があります*8。したがって，XSUBからSVを直接返す時は，必ずsv_2mortal()で揮発性にしましょう。

sv_2mortal()を掛けすぎると，Perlインタプリタが「不正にSVの解放が行われた」と文句を言ってくれますが，メモリリークについてはインタプリタは文句を言いません。したがって，不安だったらsv_2mortal()するように習慣づけておくと安全です。

さらなる学習のために

以上，XSを俯瞰しましたが，実際にXSを一から書くのは大変です。いくつかのXSモジュールを実際に読んでみたり，改造してみたり*9することをお勧めします。

Scalar-List-UtilsのXSセクションは比較的理解しやすいのではないかと思います*10。

また，Perl自身のソースコードは，その時の最新の PerlAPI *11に則って書かれているため，最良の教科書です。sv.c，av.c，pp_hot.c，universal.c
は比較的読みやすく，重要性も高いのでお勧めです。細かな挙動について知るためにはPerlのソースコードを参照するしかないことも少なくなく，XSを書くならPerlソースコードを手元に置いておくのは必須といえます。

See also:

  * perlxstut(ja) - XS のチュートリアル

  * perlxs(ja) - XS のリファレンス

  * perlapi(ja) - PerlAPI のリファレンス

  * perlguts - Perl の内部構造(データ編)

  * perlhack - Perl の内部構造(インタプリタ編)

  * perlclib - Cライブラリの代替API

Enjoy XS!

*1：使っている例を見たことはありませんが！

*2：唯一の引数として

*3：数ある引数の中の最初のものとして。アンダーバーはカンマに置き換えられると考えてよい。

*4：関数の場合

*5：マクロの場合

*6：なぜそれぞれ二つのマクロが必要なのかについてはきちんとした理由があるのですが，込み入った話になるので省略します。とにかく，ENTERとSAVETMPSのどちらも必要なのです。

*7：そして，リファレンスカウントが0になると当然解放されます

*8：正確には違います。Perlは引数スタックのSVのリファレンスカウントには触らないのです。したがって，作ったSVをそのままスタックに置いておくと，そのSVは解放されません。

*9：「このSVにsv_2mortal()を掛けるとどうなるだろう？」

*10：Cセクションはすべてバージョン間の差異を吸収するための#ifdefです。

*11：古いスタイルのPerlAPIを知る必要はほとんどありません。ppport.hというヘッダファイルを使うことにより，古いバージョンのperlでも最新のPerlAPIを使うことができるからです。</summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
		<div class="section">
			<p>元ネタ：<a href="http://d.hatena.ne.jp/perlcodesample/20091226/1264257759">Perl基礎文法最速マスター</a>(<a href="http://d.hatena.ne.jp/perlcodesample/">id:perlcodesample</a>)</p>
			<p>XSを始めるための手順といくつかの要素の解説です。C言語をある程度知っている人でも，これを読んだだけでXSの基礎をマスターしてXSを書くことができるようにはなっていません。リファレンスでもありません。</p>
			<p>XSとは，狭義ではPerlでエクステンションを書くためのマクロ言語の名前ですが，広義ではエクステンションを書くための技術の総称です。ここでは，広義のXSを俯瞰します。</p>
			<p>XSはいろいろと特殊なのでテンプレは無視で行きます。</p>
			<p>目次：</p>
			<ol>
				<li> h2xsで空のディストリビューションを作る</li>
				<li> XSファイルの構成</li>
				<li> スレッドコンテキスト</li>
				<li> SVファミリ</li>
				<li> GCとスコープ</li>
				<li> さらなる学習のために</li>
			</ol>
			<h4> h2xsで空のディストリビューションを作る</h4>
			<p>以下のコマンドで空のXSディストリビューションを作ることができます。</p>
<pre class="syntax-highlight">
h2xs <span class="synSpecial">-A</span> <span class="synSpecial">-b</span> <span class="synConstant">5</span>.<span class="synConstant">8</span>.<span class="synConstant">1</span> <span class="synSpecial">-n</span> Foo::Bar
</pre>

			<p>ディストリビューションを作るためのモジュールはModule::Starter, Module::Setupなどもありますが，最初はh2xsで十分でしょう。なによりインストールの必要がありません。</p>
			<p>ディストリビューションを作ったら，その中のディレクトリに移動してとりあえずビルドしてみます。</p>
<pre class="syntax-highlight">
<span class="synStatement">cd</span> Foo-Bar
perl Makefile.PL
make <span class="synStatement">&amp;&amp;</span> make <span class="synStatement">test</span>
</pre>

			<p>これがうまくいかなければコンパイラをセットアップする必要がありますが，省略します。WindowsならStrawberry PerlやCygwinを使うのがお勧めです。</p>
			<p>次の節に進む前に，XSファイルの先頭，Perlのヘッダファイルをインクルードする前に，<code>"#define PERL_NO_GET_CONTEXT"</code>という行を追加しておきましょう。これはスレッドコンテキストと関係があるのですが，とりあえずオマジナイと考えてかまいません。また，XSセクションには<code>"PROTOTYPES: DISABLE"</code>という行を加えておきましょう。この行がないとXSUBに自動的にプロトタイプがついてしまい，予想外の挙動を招くことになります。</p>
			<h4> XSファイルの構成</h4>
			<p>一つのXSファイルはCセクションとXSセクションに分かれています。CセクションはC言語そのもので，モジュールのユーザーからは見えません。XSセクションでXSUBを書き，これはモジュールのユーザーから見えます。</p>
			<p>たとえば，以下のようになります。</p>
<pre class="syntax-highlight">
<span class="synPreProc">#define PERL_NO_GET_CONTEXT</span>
<span class="synPreProc">#include </span><span class="synConstant">"EXTERN.h"</span>
<span class="synPreProc">#include </span><span class="synConstant">"perl.h"</span>
<span class="synPreProc">#include </span><span class="synConstant">"XSUB.h"</span>

<span class="synPreProc">#include </span><span class="synConstant">"ppport.h"</span>

=pod

C section

=cut

<span class="synStatement">MODULE</span> = Foo::Bar		<span class="synStatement">PACKAGE</span> = Foo::Bar	

<span class="synStatement">PROTOTYPES</span>: DISABLE	

=pod

XS section

=cut

<span class="synType">void</span>
hello()
<span class="synStatement">CODE</span>:
{
    PerlIO_stdoutf(<span class="synConstant">"Hello, world!</span><span class="synSpecial">\n</span><span class="synConstant">"</span>);
}
</pre>

			<p>これは，以下のコマンドで実行できます。</p>
<pre class="syntax-highlight">
make
perl <span class="synSpecial">-Mblib</span> <span class="synSpecial">-MFoo</span>::Bar <span class="synSpecial">-e</span> <span class="synStatement">'</span><span class="synConstant">Foo::Bar::hello()</span><span class="synStatement">'</span>
</pre>

			<p>なお，上の例が示すように，セクションにかかわらず任意の場所にPODを書くことができます<span class="footnote"><a href="/gfx/#f1" name="fn1" title="使っている例を見たことはありませんが！">*1</a></span>。</p>
			<h4> スレッドコンテキスト</h4>
			<p>Cセクションにいろいろ書くつもりがなければ，この節の内容は特に必要ありません。</p>
			<p>スレッドコンテキストとは，Perlインタプリタレベルでのグローバル変数を持っている構造体で，ほとんどすべてのPerlAPIの最初の引数として渡すものです。ただし，ほとんどすべてのPerlAPIは，このことを意識しなくてすむようにマクロでラップしてあります。</p>
			<p>このことを意識しなければならないのは，Cセクションに関数を書くときです。</p>
			<p>このとき，自分の関数についても，PerlAPI と同じように最初の引数にスレッドコンテキスト渡すようにしないと，その関数の内部でPerlAPIが使えません。</p>
			<p>スレッドコンテキストの宣言にはpTHX<span class="footnote"><a href="/gfx/#f2" name="fn2" title="唯一の引数として">*2</a></span>/pTHX_<span class="footnote"><a href="/gfx/#f3" name="fn3" title="数ある引数の中の最初のものとして。アンダーバーはカンマに置き換えられると考えてよい。">*3</a></span>を使います。API の呼出には aTHX/aTHX_ を使います。</p>
<pre class="syntax-highlight">
<span class="synComment">/* in C section */</span>
<span class="synType">static</span> <span class="synType">void</span>
hello(pTHX) {
    PerlIO_stdoutf(<span class="synConstant">"Hello, world!</span><span class="synSpecial">\n</span><span class="synConstant">"</span>);
}

<span class="synComment">/* IV: Integer Value */</span>
<span class="synType">static</span> <span class="synType">void</span>
increment(pTHX_ <span class="synPreProc">SV</span>* <span class="synType">const</span> sv) {
    sv_inc(sv); <span class="synComment">/* 実際には Perl_sv_inc(aTHX_ sv) に展開される */</span>
}

<span class="synStatement">MODULE</span> = Foo::Bar		<span class="synStatement">PACKAGE</span> = Foo::Bar	

<span class="synType">void</span>
hello()
<span class="synStatement">CODE</span>:
{
    hello(aTHX);
}

<span class="synType">void</span>
increment(<span class="synPreProc">SV</span>* sv)
<span class="synStatement">CODE</span>:
{
    increment(aTHX_ sv);
}
</pre>

			<p>特定のプロトタイプが必要なコールバックなどではスレッドコンテキストを受け取れないことがありますが，その場合は関数の最初で <code>dTHX;</code> 宣言をすることにより，スレッドコンテキストを定義することができます。</p>
			<h4> SVファミリ</h4>
			<p>Perlのデータは，CレベルではSV*(スカラー)，AV*(配列)，HV*(ハッシュ)などで表現されますが，これらすべてはSV*の派生クラスと考えられます。つまり，SvTYPE() や SvREFCNT_inc()/SvREFCNT_dec() などのAPIは，その引数としてどのSVファミリでも受け取れるようになっています。以後，単にSVと書くときは，SVファミリのことと考えてください。</p>
			<p>SVファミリを操作するためのAPIの数は多いので紹介はしませんが，一般に，スカラー値であれば sv_<span class="footnote"><a href="/gfx/#f4" name="fn4" title="関数の場合">*4</a></span>/Sv<span class="footnote"><a href="/gfx/#f5" name="fn5" title="マクロの場合">*5</a></span> というプレフィクスを持ち，同様に配列では av_/Av，ハッシュでは hv_/Hv というプレフィクスを持つので，ソースコードを読むときには頭に入れておくといいでしょう。</p>
			<p>なお，SVファミリの具体的な挙動については，<a href="http://perldoc.jp/docs/perl/5.10.0/perlapi.pod">perldoc perlapi</a>を参照してください。</p>
			<h4> GCとスコープ</h4>
			<p>Perlはリファレンスカウントベースのガベージコレクション機構を持っています。また，スコープと揮発性(mortality)という概念で，XSレベルでもリファレンスカウントの管理を自動化できるようになっています。</p>
			<p>XSにおけるスコープは，Perlレベルでのスコープと同じです。これは，<code>ENTER; SAVETMPS;</code> というマクロで開き，<code>FREETMPS; LEAVE;</code> というマクロで閉じます<span class="footnote"><a href="/gfx/#f6" name="fn6" title="なぜそれぞれ二つのマクロが必要なのかについてはきちんとした理由があるのですが，込み入った話になるので省略します。とにかく，ENTERとSAVETMPSのどちらも必要なのです。">*6</a></span>。</p>
			<p>そして，このスコープの中であるSVを揮発性にすると，そのSVのリファレンスカウントは，そのスコープを抜けるときに一つ減ります<span class="footnote"><a href="/gfx/#f7" name="fn7" title="そして，リファレンスカウントが0になると当然解放されます">*7</a></span>。この処理はスコープの中で例外が起きたときでもきちんと行われるので，手動でリファレンスカウントを減らすよりも安全です。SVを揮発性にするには，sv_2mortal()を使います。初めから揮発性のSVがほしいときは，sv_newmortal()が，SVの揮発性コピーがほしいときはsv_mortalcopy()を使います。</p>
<pre class="syntax-highlight">
<span class="synComment">/* in C section */</span>
<span class="synType">static</span> <span class="synType">void</span>
foo(pTHX) {
    <span class="synPreProc">SV</span>* sv;
    ENTER;
    SAVETMPS;

    sv = sv_newmortal();
    sv_setpvs(sv, <span class="synConstant">"Hello, world!</span><span class="synSpecial">\n</span><span class="synConstant">"</span>);
    PerlIO_stdoutf(<span class="synConstant">"%"</span>SVf, sv); <span class="synComment">/* -&gt; "Hello, world!" */</span>

    FREETMPS;
    LEAVE;
    <span class="synComment">/* ここでsvはすでに解放されている */</span>
}
</pre>

			<p>SvREFCNT_inc()とSvREFCNT_dec()でリファレンスカウントを手動で操作することもできますが，慣れないうちは手動で操作する代わりにsv_mortalcopy()とスコープメカニズムを使ったほうが安全です。</p>
			<p>なお，すべてのXSUBは呼び出されるときにスコープで囲まれます。また，XSUBからの戻り値は揮発性のSVでなければならないという呼出規約があります<span class="footnote"><a href="/gfx/#f8" name="fn8" title="正確には違います。Perlは引数スタックのSVのリファレンスカウントには触らないのです。したがって，作ったSVをそのままスタックに置いておくと，そのSVは解放されません。">*8</a></span>。したがって，XSUBからSVを直接返す時は，必ずsv_2mortal()で揮発性にしましょう。</p>
			<p>sv_2mortal()を掛けすぎると，Perlインタプリタが「不正にSVの解放が行われた」と文句を言ってくれますが，メモリリークについてはインタプリタは文句を言いません。したがって，不安だったらsv_2mortal()するように習慣づけておくと安全です。</p>
			<h4> さらなる学習のために</h4>
			<p>以上，XSを俯瞰しましたが，実際にXSを一から書くのは大変です。いくつかのXSモジュールを実際に読んでみたり，改造してみたり<span class="footnote"><a href="/gfx/#f9" name="fn9" title="「このSVにsv_2mortal()を掛けるとどうなるだろう？」">*9</a></span>することをお勧めします。</p>
			<p><a href="http://search.cpan.org/dist/Scalar-List-Utils/">Scalar-List-Utils</a>のXSセクションは比較的理解しやすいのではないかと思います<span class="footnote"><a href="/gfx/#f10" name="fn10" title="Cセクションはすべてバージョン間の差異を吸収するための#ifdefです。">*10</a></span>。</p>
			<p>また，Perl自身のソースコードは，その時の最新の PerlAPI <span class="footnote"><a href="/gfx/#f11" name="fn11" title="古いスタイルのPerlAPIを知る必要はほとんどありません。ppport.hというヘッダファイルを使うことにより，古いバージョンのperlでも最新のPerlAPIを使うことができるからです。">*11</a></span>に則って書かれているため，最良の教科書です。sv.c，av.c，pp_hot.c，universal.c は比較的読みやすく，重要性も高いのでお勧めです。細かな挙動について知るためにはPerlのソースコードを参照するしかないことも少なくなく，XSを書くならPerlソースコードを手元に置いておくのは必須といえます。</p>
			<p>See also:</p>
			<ul>
				<li> <a href="http://perldoc.perl.org/perlxstut.html">perlxstut</a>(<a href="http://perldoc.jp/docs/perl/5.10.0/perlxstut.pod">ja</a>) - XS のチュートリアル</li>
				<li> <a href="http://perldoc.perl.org/perlxs.html">perlxs</a>(<a href="http://perldoc.jp/docs/perl/5.10.0/perlxs.pod">ja</a>) - XS のリファレンス</li>
				<li> <a href="http://perldoc.perl.org/perlapi.html">perlapi</a>(<a href="http://perldoc.jp/docs/perl/5.10.0/perlapi.pod">ja</a>) - PerlAPI のリファレンス</li>
				<li> <a href="http://perldoc.perl.org/perlguts.html">perlguts</a> - Perl の内部構造(データ編)</li>
				<li> <a href="http://perldoc.perl.org/perlhack.html">perlhack</a> - Perl の内部構造(インタプリタ編)</li>
				<li> <a href="http://perldoc.perl.org/perlclib.html">perlclib</a> - Cライブラリの代替API</li>
			</ul>
			<p>Enjoy XS!</p>
		</div>
		<div class="footnote">
			<p class="footnote"><a href="/gfx/#fn1" name="f1">*1</a>：使っている例を見たことはありませんが！</p>
			<p class="footnote"><a href="/gfx/#fn2" name="f2">*2</a>：唯一の引数として</p>
			<p class="footnote"><a href="/gfx/#fn3" name="f3">*3</a>：数ある引数の中の最初のものとして。アンダーバーはカンマに置き換えられると考えてよい。</p>
			<p class="footnote"><a href="/gfx/#fn4" name="f4">*4</a>：関数の場合</p>
			<p class="footnote"><a href="/gfx/#fn5" name="f5">*5</a>：マクロの場合</p>
			<p class="footnote"><a href="/gfx/#fn6" name="f6">*6</a>：なぜそれぞれ二つのマクロが必要なのかについてはきちんとした理由があるのですが，込み入った話になるので省略します。とにかく，ENTERとSAVETMPSのどちらも必要なのです。</p>
			<p class="footnote"><a href="/gfx/#fn7" name="f7">*7</a>：そして，リファレンスカウントが0になると当然解放されます</p>
			<p class="footnote"><a href="/gfx/#fn8" name="f8">*8</a>：正確には違います。Perlは引数スタックのSVのリファレンスカウントには触らないのです。したがって，作ったSVをそのままスタックに置いておくと，そのSVは解放されません。</p>
			<p class="footnote"><a href="/gfx/#fn9" name="f9">*9</a>：「このSVにsv_2mortal()を掛けるとどうなるだろう？」</p>
			<p class="footnote"><a href="/gfx/#fn10" name="f10">*10</a>：Cセクションはすべてバージョン間の差異を吸収するための#ifdefです。</p>
			<p class="footnote"><a href="/gfx/#fn11" name="f11">*11</a>：古いスタイルのPerlAPIを知る必要はほとんどありません。ppport.hというヘッダファイルを使うことにより，古いバージョンのperlでも最新のPerlAPIを使うことができるからです。</p>
		</div>
</div>
    </content>
    <category term="Perl"/>
    <published>2010-02-02T15:20:06+09:00</published>
    <updated>2010-02-02T15:20:06+09:00</updated>
    <author>
      <name>gfx</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://d.hatena.ne.jp/gfx/20100202/1265091606</id>
  </entry>
  <entry>
    <title>Tip: Install a CPAN module directly from URL</title>
    <link rel="alternate" href="http://gugod.org/2010/02/tip-install-a-cpan-module-directly-from-url.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I wonder how many people know this. With CPANPLUS, you can install any
cpan module directly from its tarball URL:

cpanp -i http://search.cpan.org/CPAN/authors/id/M/MI/MIYAGAWA/Plack-0.99_02.tar.gz

Very handy, indeed.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>I wonder how many people know this. With CPANPLUS, you can install any cpan module directly from its tarball URL:</p>

<pre><code>cpanp -i http://search.cpan.org/CPAN/authors/id/M/MI/MIYAGAWA/Plack-0.99_02.tar.gz
</code></pre>

<p>Very handy, indeed.</p>

        

    </div>
    </content>
    <category term="Perl cpan cpanp tip"/>
    <published>2010-02-02T04:38:07Z</published>
    <updated>2010-02-02T04:38:07Z</updated>
    <author>
      <name>gugod</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:gugod.org,2010://2.651</id>
  </entry>
  <entry>
    <title>When Context Gets Complicated (and why it's not a problem)</title>
    <link rel="alternate" href="http://www.modernperlbooks.com/mt/2010/02/when-context-gets-complicated-and-why-its-not-a-problem.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">In Essential Skills for Perl 5 Programmers I mentioned that no one can be
an adept Perl programmer without understanding context. This trips up
many, many people -- and you often hear (unfair) criticisms of Perl 5
based on misunderstandings and guesses about how context works.

Context is reasonably easy to explain. (The previous sentence is
grammatically correct.) Contexts is not difficult to understands. (The
previous sentence is grammatically incorrect, even if you speak the
Queen's English.)

If you can find the errors in the previous paragraph, you can understand
quantity context in Perl 5: like subject-verb agreement in terms of
number, expressions in Perl 5 can behave differently in contexts that
imply zero, one, or more results.

fetch_something_awesome();              # void   context
my $item  = fetch_something_awesome();  # scalar context
my @items = fetch_something_awesome();  # list   context

Context gets a little bit trickier when you need to coerce what would
normally be one context into another:

my ($item) =        fetch_something_awesome(); # list   context
push @items, scalar fetch_something_awesome(); # scalar context

If you know the visual cues (if you don't randomly sprinkle punctuation
about your program until it works), those are easy to understand as well.

The subtlety comes when dealing with complex contexts, usually with
nested expressions:

# list context, thanks to say
say reverse $name;

my %values =
(
    # list context, thanks to hash assignment
    name =&gt; get_name(),
    rank =&gt; get_rank(),
);

# list context (param flattening)
$screen-&gt;flip( $fleet-&gt;get_spaceships() );

This is often where more fair criticisms of Perl 5 suggest that context
may not be worth it, because you have to understand what a line of code
means and what it implies to read it correctly.

There's a fair point there, but it's also silly in some ways. Skimming
code which calls other functions may give you some idea of what those
functions do, but you rely only on the names of those functions and not
their documentation to tell you any other details. Do they modify global
or thread-local variables? Do they have caching or performance
characteristics? Do they block? Do they require special initialization or
error handling? Do they return special values?

The valid point is that chaining multiple expressions into complex
compound expressions can have interesting effects. (I see this in Haskell
code often; invisible partial application means that I personally can't
skim Haskell code without tracking down the arity of functions to figure
out what happens where.)

That's no argument against language features. It's an argument against
making expressions more complex than necessary. Note that the same
argument applies against complex prefix-unless expressions. unless can be
amazingly useful when used properly. If you abuse it, you make amazing
problems. Don't make problems.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>In <a href="http://www.modernperlbooks.com/mt/2010/01/essential-skills-for-perl-5-programmers.html">Essential Skills for Perl 5 Programmers</a> I mentioned that no one can be an adept Perl programmer without understanding context.  This trips up many, many people -- and you often hear (unfair) criticisms of Perl 5 based on misunderstandings and guesses about how context works.</p>

<p>Context is reasonably easy to explain.  (The previous sentence is grammatically correct.)  Contexts is not difficult to understands.  (The previous sentence is grammatically incorrect, even if you speak the Queen's English.)</p>

<p>If you can find the errors in the previous paragraph, you can understand
quantity context in Perl 5: like subject-verb agreement in terms of number,
expressions in Perl 5 can behave differently in contexts that imply zero, one,
or more results.</p>

<pre><code>fetch_something_awesome();              # void   context
my $item  = fetch_something_awesome();  # scalar context
my @items = fetch_something_awesome();  # list   context</code></pre>

<p>Context gets a little bit trickier when you need to coerce what would normally be one context into another:</p>

<pre><code>my ($item) =        fetch_something_awesome(); # list   context
push @items, scalar fetch_something_awesome(); # scalar context</code></pre>

<p>If you know the visual cues (if you don't randomly sprinkle punctuation about your program until it works), those are easy to understand as well.</p>

<p>The subtlety comes when dealing with complex contexts, usually with nested expressions:</p>

<pre><code># list context, thanks to say
say reverse $name;

my %values =
(
    # list context, thanks to hash assignment
    name =&gt; get_name(),
    rank =&gt; get_rank(),
);

# list context (param flattening)
$screen-&gt;flip( $fleet-&gt;get_spaceships() );</code></pre>

<p>This is often where more fair criticisms of Perl 5 suggest that context may not be worth it, because you have to understand what a line of code means and what it implies to read it correctly.</p>

<p>There's a fair point there, but it's also silly in some ways.  Skimming code which calls other functions may give you some idea of what those functions do, but you rely only on the names of those functions and not their documentation to tell you any other details.  Do they modify global or thread-local variables?  Do they have caching or performance characteristics?  Do they block?  Do they require special initialization or error handling?  Do they return special values?</p>

<p>The valid point is that chaining multiple expressions into complex compound expressions can have interesting effects.  (I see this in Haskell code often; invisible partial application means that I personally can't skim Haskell code without tracking down the arity of functions to figure out what happens where.)</p>

<p>That's no argument <em>against</em> language features.  It's an argument
against making expressions more complex than necessary.  Note that the same
argument applies against complex prefix-<code>unless</code> expressions.
<code>unless</code> can be amazingly useful when used properly.  If you abuse
it, you make amazing problems.  Don't make problems.</p>

        
    </div>
    </content>
    <category term="maintainability perl perl 5 perl programming"/>
    <published>2010-02-01T23:39:24Z</published>
    <updated>2010-02-01T23:39:24Z</updated>
    <author>
      <name>chromatic</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:www.modernperlbooks.com,2010:/mt//1.145</id>
  </entry>
  <entry>
    <title>On Frameworks ...</title>
    <link rel="alternate" href="http://stevan-little.blogspot.com/2010/02/on-frameworks.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">So I was reading zby's latest blog post on frameworks and libraries. On
some level I agree with him that often times frameworks are basically
just codified "convention", but I really don't see this as a bad thing,
and here is why.
As I see it, the purpose of a library is to provide generic re-usable
code that can be used in many different contexts. The purpose of a
framework is to provide a set of guidelines/conventions/best-practices
which a developer can then build upon, therefore avoiding the need to set
those guidelines/dictate those conventions/determine those best practices
themselves.
Some frameworks are more opinionated and complex (RoR, Catalyst, etc) and
push/force you into their way of thinking, the benefit being that they
also provide you with lots of building blocks that often times are
zero-conf. While others (Dancer, Web::Simple, Mojolicious::Lite, etc) are
more focused and purposefully simple, they leave many problems unsolved
therefore allowing more freedom for the developer. Each of these
approaches has merit and neither is truly superior in all contexts, which
brings me to Plack and why I think this explosion of "frameworks" is a
really good thing.
The ubiquity of Plack means that all these frameworks can be (fairly)
easily used within the same application (or set of applications). It
should (eventually) be very easy to have your Catalyst application
running next to your Dancer application, running next to your WebNano
application, all sharing the same session data, user information, etc.
through Plack::Middleware components and mounted under a single
Plack::App::URLMap and controlled easily using plackup.</div>
    </summary>
    <content type="html">&lt;div&gt;So I was reading &lt;a href="http://perlalchemy.blogspot.com/2010/02/frameworks-are-framing-libraries-are.html"&gt;zby's latest blog post on frameworks and libraries&lt;/a&gt;. On some level I agree with him that often times frameworks are basically just codified "convention", but I really don't see this as a bad thing, and here is why.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As I see it, the purpose of a library is to provide generic re-usable code that can be used in many different contexts. The purpose of a framework is to provide a set of guidelines/conventions/best-practices which a developer can then build upon, therefore avoiding the need to set those guidelines/dictate those conventions/determine those best practices themselves.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some frameworks are more opinionated and complex (&lt;a href="http://rubyonrails.org/"&gt;RoR&lt;/a&gt;, &lt;a href="http://search.cpan.org/dist/Catalyst-Runtime/"&gt;Catalyst&lt;/a&gt;, etc) and push/force you into their way of thinking, the benefit being that they also provide you with lots of building blocks that often times are zero-conf. While others (&lt;a href="http://search.cpan.org/dist/Dancer/"&gt;Dancer&lt;/a&gt;, &lt;a href="http://search.cpan.org/dist/Web-Simple/"&gt;Web::Simple&lt;/a&gt;, &lt;a href="http://search.cpan.org/~kraih/Mojo-0.999914/lib/Mojolicious/Lite.pm"&gt;Mojolicious::Lite&lt;/a&gt;, etc) are more focused and purposefully simple, they leave many problems unsolved therefore allowing more freedom for the developer. Each of these approaches has merit and neither is truly superior in all contexts, which brings me to &lt;a href="http://plackperl.org/"&gt;Plack&lt;/a&gt; and why I think this explosion of "frameworks" is a really good thing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The ubiquity of &lt;a href="http://plackperl.org/"&gt;Plack&lt;/a&gt; means that all these frameworks can be (fairly) easily used within the same application (or set of applications). It should (eventually) be very easy to have your &lt;a href="http://search.cpan.org/dist/Catalyst-Runtime/"&gt;Catalyst&lt;/a&gt; application  running next to your &lt;a href="http://search.cpan.org/dist/Dancer/"&gt;Dancer&lt;/a&gt; application, running next to your &lt;a href="http://github.com/zby/WebNano"&gt;WebNano&lt;/a&gt; application, all sharing the same session data, user information, etc. through &lt;a href="http://search.cpan.org/dist/Plack/"&gt;Plack::Middleware&lt;/a&gt; components and mounted under a single &lt;a href="http://search.cpan.org/dist/Plack/"&gt;Plack::App::URLMap&lt;/a&gt; and controlled easily using &lt;a href="http://search.cpan.org/dist/Plack/"&gt;plackup&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img alt=""&gt;&lt;/div&gt;</content>
    <category term="mojo frameworks dancer catalyst plack perl"/>
    <published>2010-02-01T22:58:00Z</published>
    <updated>2010-02-01T22:58:00Z</updated>
    <author>
      <name>Stevan Little</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:tag:blogger.com,1999:blog-5205671691245928993.post-949072862338018194</id>
  </entry>
  <entry>
    <title>Set Phasers to Stun!</title>
    <link rel="alternate" href="http://perlgeek.de/blog-en/perl-6/set-phasers-to-stun.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Did you ever wonder how BEGIN, CHECK, END and so on are called in Perl?
Well, they didn't have a good name, until recently.

The Perl 6 spec listed them under closure traits, which is unwieldy, and
not really exact either. Now they are called phasers, because they tell
you which execution phase the block or statement runs in.

There are so many possible puns that I'll refrain from writing any.</div>
    </summary>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">

<p>Did you ever wonder how <code>BEGIN</code>, <code>CHECK</code>,
<code>END</code> and so on are called in Perl? Well, they didn't have a good
name, until <a href="http://irclog.perlgeek.de/perl6/2009-11-06#i_1695188">recently</a>.</p>

<p>The Perl 6 spec listed them under <em>closure traits</em>, which is
unwieldy, and not really exact either. <a href="http://perlcabal.org/svn/pugs/revision/?rev=29004">Now they are called
<em>phasers</em></a>, because they tell you which execution phase the block or
statement runs in.</p>

<p>There are so many possible puns that I'll refrain from writing any.</p>



</div>
    </content>
    <author>
      <name>Moritz Lenz</name>
    </author>
    <id>tag:ironman.enlightenedperl.org,2006:http://perlgeek.de/blog-en/perl-6/set-phasers-to-stun.html</id>
  </entry>
  <entry>
    <title>Musing and the future of feather and the Pugs repository</title>
    <link rel="alternate" href="http://perlgeek.de/blog-en/perl-6/musings-on-feather-and-pugscode.html" type="text/html"/>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">(This blog post will probably only interest Perl 6 hackers, since it
talks only about infrastructure.)

One of the central pieces of Perl 6 infrastructure is the Pugs svn
repository. It holds not only the Pugs source code, but also lots of
other Perl 6 projects:

  * Specification

  * Test suite

  * STD.pm (the standard grammar)

  * SMOP

  * mildew and mildew-js

  * sprixel

  * vill

  * mp6, kp6, perlito

  * elf

  * various websites (perl6.org, pugscode.org, perlcabal.org/syn/)

  * a host of scripts related to keep things running (rebuild the HTML
    version of the synopsis; smartlink checking; cronjobs for updating
    websites etc.)

  * various documentation efforts

  * An unknown number of projects more or less related to Perl 6

It's huge, but at the same time it's very practical: anybody who is
interested can get write access very easily, create a new subfolder for a
new project, or can fix a typo in someone else's README file without
asking for commit access first.

The pugs repo is also viral: Anybody with commit access and invite new
committers. Despite what you might think of it: it actually works in
practice, so far I haven't seen a single case of abuse.

The pugs repository is hosted on feather, a server kindly provided by
Juerd and his company. It contains three virtualized servers,
feather{1,2,3}. feather2 is used for "sensitive" data (for example an IRC
bot that has API keys for various github accounts, and the perl6.org
website). Only a handful of "trusted" users have an account there.
feather3 is used for low security stuff like evalbots which might go
astray.

feather1 holds all the rest. That means the pugs repository, commitbit
(the software we use for handing out commit bits and resetting svn
passwords), various websites, and a whole bunch of Perl 6 developers and
users have a shell account there, for trying out Perl 6 and hosting their
screen + irssi sessions there.

I was about to write feather1 is maintained by a bunch of volunteers, but
that would be a lie. It is "maintained" on an as-needed basis by whoever
has time and feels half-way competent. It is an "interesting" mixture of
Debian unstable and experimental. And it's becoming unmaintainable.

It seems clear what to do: set up a fourth virtual machine, set up a
replacement for feather1, and en passant migrate some things (like
websites and the pugs repo) to feather2.

But wait! There is an issue. There's always an issue. Setting up a new
machine and migrating services takes time. Lots of time. And nobody wants
to do it right now. Quite understandably.

Take the pugs repository for example: you might think it's easy en