Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

AndyArmstrong (7200)

  (email not shown publicly)
Thursday July 02, 2009
05:24 AM

Safari 4 likes clicking

Installing Safari 4 had a pretty strange effect for me: Lights in the house switched on and off at random.

It turns out that Safari likes to visit your favourite pages periodically to update its Top Sites browser. Which is fine unless some of the lights in your house are controlled by a web interface which uses GET for the light switch buttons.

Since it's private to the house network I hadn't bothered to password protect it. I assume Safari would have left it alone if I had. On a hunch I fixed the problem by switching the lighting control page to https - and it seems to have worked.

I can't help wondering 1) how many intranets it's attacked already and 2) does it know to refrain from clicking on sites that use cookie based auth (RT?) and if so, how?

Wednesday June 17, 2009
08:03 AM

Test::Harness on Github

For the last few years Test::Harness has lived in subversion. Over the last couple of weeks I've been moving my modules to Github and yesterday I moved Test::Harness. You can find it here:

As an aside, I assume everyone who hasn't been bitten by the git bug is getting sick of hearing about projects moving to Github. To you I say this: two weeks ago I was that sceptic - but git really is that good.

Tuesday April 15, 2008
10:32 AM

Oslo QA Hackathon Report

Last week I was in Oslo for the Perl QA hackathon and then the GoOpen conference. My objective for the hackathon was to bring parallel testing to the Perl core. Test::Harness already supports parallel testing but has a simpleminded idea of scheduling. To successfully run Perl's own tests in parallel it needs to handle scheduling rules. Some core tests that shouldn't be run while others from the same group are running because they do things like using the same temporary file.

Although this work is for Perl core it will eventually benefit all users of Test::Harness who'd like parallel testing with scheduling rules.

Well, I didn't get it done. Tux wrote a simple set of rules and theoretically after that it was a Simple Matter of Programming - but it's programming that hasn't happened yet...

I decided that it wasn't a good use of my time to withdraw into my programming shell given the unprecedented opportunity to work with other Perl QA folk on issues such as the future direction of the TAP protocol. For once the circumstances dictated that talk was more valuable than action and I can program any time :)

So I spent most of my time in the TAP room contributing to the debate about how we integrate structured diagnostics and nested TAP without causing too much backwards compatibility breakage. We nearly reached consensus too; decisions were reached on most of the major areas. Over on the TAP-L mailing list there's still a debate on the precise form that nested TAP should take but we're much closer to agreement and a clear route forward than we were.

For me, the hackathon was about more than specific tasks. It was a chance for a group of people who normally communicate on email and IRC to meet face to face. It turns out that even when we're not talking about Perl we can sustain an interesting conversation. Who knew?

I'm working on the implementation of the parallel testing scheduling rules now, feeling optimistic about the future of TAP and happy to have had the chance to spend time with such a great bunch of comrades.

I'd like to thank my sponsors for the trip,, hackathon hosts Linpro, brilliant organiser Salve Nilsen and all the local crew who made us so welcome.

Here's a list of others' reports:

Thursday February 28, 2008
02:48 PM

Perl debugger: stop at a specific test number

I like data driven tests. The general pattern is a big array of test cases and some driver code at the bottom that loops over the cases applying the same assertions to each of them.

That's all well and good until you want to use the Perl debugger to step through test #1967 of 2673. There's no good place to set a break point because the driver loop will execute many times before it hits the test you want to single step through. You can fake it like this:

if (Test::Builder->new->current_test >= 85) {
    $DB::single = 1;

Setting $DB::single to a true value makes the debugger break at the following line. It'd be much nicer though to be able to set a magic breakpoint in the debugger that'd stop at test #1967. Add the following code to your ~/.perldb and that's exactly what you'll be able to do.

my @opts = qw( windowSize=30 );

if ( $] >= 5.010000 ) {
    push @opts, "HistFile='" . glob( '~/.perldb_history' ) . "'";

parse_options( $_ ) for @opts;

@DB::testbreak = ();

# Monkeypatch cmd_b (set breakpoint)
my $cmd_b = \&DB::cmd_b;
*DB::cmd_b = sub {
    my ( $cmd, $line, $dbline ) = @_;
    if ( $line =~ /\s*#\s*(\d+(?:\s*,\s*\d+)*)$/ ) {
        my %seen;
        @DB::testbreak = grep { !$seen{$_}++ }
          sort { $a <=> $b } ( split( /\s*,\s*/, $1 ), @DB::testbreak );
    else {
        $cmd_b->( @_ );

sub afterinit {
    $trace |= 4;    # Enable watchfunction

sub watchfunction {
    if ( @DB::testbreak && exists $INC{'Test/'} ) {
        my $next = Test::Builder->new->current_test + 1;
        if ( $next >= $DB::testbreak[0] ) {
            shift @DB::testbreak
              while @DB::testbreak && $next >= $DB::testbreak[0];

            my $depth = 1;
            while ( 1 ) {
                my ( $package, $file, $line ) = caller $depth;
                last unless defined $package;
                last unless $package =~ /^Test::/;
            $DB::stack[ -$depth ] = 1;


It modifies the debugger's 'b' (breakpoint) command so that you can type:

  DB<1> b #1967
  DB<1> c

That'll run the tests until immediately after test #1966 and then stop, ready for the setup to the test you're interested in. Regular breakpoints still work as normal.

It's a little rough and ready. It decides which scope to stop in by unwinding the call stack skipping past any packages that are called Test::* - if your package naming doesn't work like that you'll have to hack it about a bit.

If you have any improvements please let me know.

Saturday February 23, 2008
01:38 PM

64 bit Fedora Core shell account?

I'm currently attempting to resolve a problem that the Red Hat folks are having with IPC::ShareLite on 64 bit Fedora Core with Perl 5.10. It's quite important; in fact it's critical to getting 5.10 on FC.

Unfortunately I don't own a 64 bit box. It seems (thanks Nicholas) that it might be possible to reproduce the problem using a Perl built with 64 bit ints on a non-64 bit platform - but I've had no luck in that direction yet and, in any case, I'd like to test on a 64 bit machine just to be sure.

Is there anyone out there in Perl land who could provide me with a temporary shell account on a 64 bit Fedora Core machine? That'd have to be someone who didn't mind me burning enough CPU cycles to build Perl 5.10 from source.

If you can help with getting 5.10 into Fedora by providing access to a suitable box please drop me a line and earn the eternal gratitude of, well, everyone really.


Saturday January 19, 2008
05:19 PM

It feels good to get rid of those four lines

This has bothered me far more than it should. I quite often end up writing test code that looks like this:

    my @log = ();

    no warnings 'redefine';
    *Some::Package::some_func = sub { push @log, [@_] };

    sub get_log {
        my @old_log = @log;
        @log = ();
        return @old_log;

# Then some tests that call subroutines that end up calling some_func.

The idea is to monkeypatch (Perl word of the week) the module I'm testing so I can make sure it calls some_func with the right arguments. For example with TextMate::JumpTo I wanted to test that it was going to invoke /usr/bin/open with the correct args - without actually going through with it and opening something. I didn't want the tests to spew a bunch of random windows into the user's text editor.

None of that is what bothers me. What I find troubling is that get_log is five lines of code just to read and reset the contents of a list. That's really quite upsetting, right?

Today I decided I could endure it no longer (I may be being a little theatrical here) so I spent some time thinking about it. Ideally I'd like to do away with the temporary variable altogether but I can't see a way to do that. Instead I've settled for this:

    sub get_log { ( my @got, @log ) = @log }

It's not especially pretty but it's better. That temporary still bugs me though...

Ads by Boggle
Obsessive? Compulsive? Need Help?
No expensive therapy! No painful brain surgery! You can help yourself. Just step away from the keyboard, take a walk, smell the fresh air. YOU ARE FREE!

10:49 AM

Integrating TextMate with the Perl debugger

I've been stepping through a lot of code in the Perl debugger recently. The debugger has a bit of a forbidding reputation but it's not too bad once your muscle memory has got the essential commands down.

Once thing that would really help me though would be to have my text editor (TextMate) track the current debugger file and line. Then, when I wanted to see the code around the current location, I could just flip to my editor instead of hunting around with the debugger's code viewing commands.

TextMate registers a handler for the txmt:// URL scheme that can be used to send it to a particular file, line and column (you can read more about that here).

Mac OS has /usr/bin/open which allows an arbitrary URL (or file or application) to be opened from the command line.

The Perl debugger recognises a function watchfunction, defined in ~/.perldb and calls it for every line it executes.

Throwing all those ingredients together gives us TextMate::JumpTo - a module to remotely control TextMate's current location - and this ~/.perldb file which tells the debugger to sync its position with TextMate:

use TextMate::JumpTo qw(jumpto);

sub afterinit {
    $trace |= 4;    # Enable watchfunction

    # Needed to work out where filenames are relative to
    chomp( $base_dir = `pwd` );

sub watchfunction {
    my ( $package, $file, $line ) = @_;
    local $trace = 0;
    if ( $file =~ /^\(eval\s+\d+\)\[(.+?):(\d+)\]/ ) {
        $file = $1;
        $line += $2 - 1;
    $file = File::Spec->rel2abs( $file, $base_dir );
    jumpto( file => $file, line => $line, bg => 1 )
      if substr( $file, 0, length( $base_dir ) ) eq $base_dir;

Now I just debug normally and any time I want to see the code around the current line I switch to the editor and there it is. It's not quite full editor integration but it immediately makes my life a lot easier.

Sunday January 06, 2008
11:42 AM


Since installing Mac OS 10.5 I've been falling in love with dtrace. I'd like to have dtrace instrumentation built into Perl as standard. Last night I started playing around with Alan Burlison's experimental dtrace patch and in particular with Richard Dawe's modified version of Alan's patch.

I made some progress and got the patch to apply cleanly against bleadperl and made a couple of changes (simplifications actually) to correspond with how dtrace itself has evolved.

This morning it occurred to me that I might be able to add the dtrace probes to a replacement runops loop instead of making it a compile time option for Perl itself. As a result I've just released Devel::DTrace.

Having launched a Perl process like this

perl -MDevel::DTrace

you can attach to it with dtrace and watch the subroutine calls go by.

For the next release of Devel::DTrace I plan to have it build a custom probe-enabled interpreter, dtperl (which is quite simple) which will be nearly as good as having probes hard wired into Perl.

I'd still like to get dtrace into core but doing so depends on minimising the performance hit that's incurred. At the moment the probe code works out the subroutine name, file and line number for every entry and exit even if the probe is disabled. The recommended solution (as per Alan's article linked above) is to move that decode logic out of Perl and into dtrace - but that's not trivial because the code has to do different things depending on how Perl is built.

In the mean time if you have a system that supports dtrace please give Devel::DTrace a try.

Sunday December 30, 2007
09:31 AM

Add your Perl to Ohloh

Ohloh tracks open source projects that have public version control repositories. Currently more than 10,000 projects are listed of which more than 2,000 use Perl. They've scanned nearly 59,000,000 lines of Perl.

Ironically if it were not for the CPAN (surely one of the world's most valuable collections of free software) Perl would, I believe, be even better represented. As this graph shows Perl doesn't feature particularly strongly in Ohloh's commit stats. Projects written in languages that don't have the benefit of a dedicated archive like CPAN tend to be hosted on Sourceforge or Google Code which automatically gets them a public repository that Ohloh can scan. CPAN modules tend to live between the author's computer and the CPAN and remain largely invisible to the wider community.

If you're a CPAN author whose modules are not listed on Ohloh consider adding them. If your code is in a public repository list that too. Let's get a more accurate picture of how much code the CPAN represents.

Sceptics will note that Ohloh's LoC (Lines of Code) and comment ratio metrics are flawed, tending to favour verbose languages and (I think) ignoring embedded POD. My impression is that the Ohloh team are actively working to improve their metrics. If Perl is well represented they will have a greater incentive to get the metrics right for Perl.

Show the rest of the free software world just how much high quality code we're cranking out. Add your Perl project to Ohloh today.

Friday December 28, 2007
07:31 AM

Why Perl 6 needs to be deemphasized and renamed: a response

Paul Cory would like to rebrand Perl 6 into the shadows. It's the kind of Stalinist revisionism favoured by corporations that realise that their "next big thing" has become an embarrassing albatross.

Here are his reasons:

1) It emphasises the "inadequacies" of Perl 5.

All languages have inadequacies, imperfections, miss-features, cruft. Perl 5 is no different. Fortunately, instead of brushing them under the rug, the Perl community is actively seeking to right those wrongs. A question: would you rather use a language that's maintained by people who are a) in denial about it's inadequacies or b) actively developing a new language based on recognised shortcomings? I hope that's a rhetorical question.

2) It makes the development community look unorganized, at best. People comparing at the development pace of Python, Ruby and PHP to Perl 6 are likely to come to harsher conclusions about the community's focus, viability and competence, based on Perl 6's seven-year, and counting, gestation period.

Those hypothetical people are wrong and I don't want to be part of a community that panders to their views. The Perl 5 Porters are doing a great job of continuously improving Perl 5. The Perl 6 team are laying the foundations for the next generation of Perl. Perl 5 and Perl 6 have a mutually beneficial relationship: features, tools and ideas are traded freely between the two groups. It's healthy, responsible and creative.

Python and Ruby have, to their credit, somewhat similar splits between far sighted strategic development and tactical improvements to the current language generation. PHP is a bizarre bazaar that does not provide a model other language communities should emulate.

3) It creates uncertainty: what happens to Perl 5 when Perl 6 finally drops? How much new stuff will I have to learn? How will my existing code work, or not, if I upgrade? Why should I invest time in Perl 5 if Perl 6 is just around the corner, and will be far superior?

Learning to deal with an uncertain future comes with the territory of computing. Continual improvement necessarily means that things will change.

Perl 6 is visible proof that we have vision. Perl 5 is visible proof that we can maintain an extremely high quality programming language. These facts combined should give observers confidence about the health of Perl. As a community we certainly need to work to allay fears and calibrate expectations. But let's not start by hiding one of our greatest assets, ok?

4) It creates frustration inside the community. Perl 6 has been "coming soon" for 7.5 years now. It's hard to remain excited about something that long with no payoff.

Welcome to the world of free software. Instead of waiting for Godot we can go and meet him half way; help him carry his load. Let's be explicit here: if Perl is part of your life or career and you're tired of waiting for Perl 6 help make it happen.

You don't have to contribute code to help. Learn more about Perl 6 so you can explain it to others. If you find it hard to learn make it easier for others: write an article that explains some of the important points, give talks, learn so you can teach.

5) The story is confusing: Pugs? Haskell? Parrot? Two development tracks? I thought this was about Perl? Yes, I have an idea of what those things are, but most folks outside the community (and a fair few inside, I'd wager) don't know, don't care, and shouldn't have to.

If the story is confusing we need to tell it more clearly. That doesn't justify changing the underlying technical narrative.

In a commodified world criticism and spending discretion are the consumer's only levers. We crave influence over the things we consume. In the absence of direct influence over a product's design we use criticism as a proxy for control. We hope that they'll make the next version better as a result.

Criticism is still valid in the free software world but it's importance is de-emphasised. You can criticise or you can help. In fact you can criticise and help.

It's important that Perl 6 is not immune from scrutiny but if you're frustrated that it's taking a while then volunteer. The Perl 6 team is small at the moment; small enough that a few well placed contributions can make a real difference. Let's not default to bitching about it when we have the opportunity of contributing to its success.