Stories
Slash Boxes
Comments

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

AndyArmstrong (7200)

AndyArmstrong
  (email not shown publicly)
http://hexten.net/

  Perl debugger: stop at a specific test number 2008-02-28 15:48 AndyArmstrong

Submitted by AndyArmstrong on 2008.02.28 15:48
AndyArmstrong writes "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/Builder.pm'} ) {
        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::/;
                $depth++;
            }
            $DB::stack[ -$depth ] = 1;
        }
    }

    return;
}

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.

"

  64 bit Fedora Core shell account? 2008-02-23 14:39 AndyArmstrong

Submitted by AndyArmstrong on 2008.02.23 14:39
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.

Thanks.

  It feels good to get rid of those four lines 2008-01-19 18:19 AndyArmstrong

Submitted by AndyArmstrong on 2008.01.19 18:19
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!

  Integrating TextMate with the Perl debugger 2008-01-19 11:49 AndyArmstrong

Submitted by AndyArmstrong on 2008.01.19 11:49
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.

  Devel::DTrace 2008-01-06 12:42 AndyArmstrong

Submitted by AndyArmstrong on 2008.01.06 12:42
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 someprog.pl

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.

  Add your Perl to Ohloh 2007-12-30 10:31 AndyArmstrong

Submitted by AndyArmstrong on 2007.12.30 10:31
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.

  Why Perl 6 needs to be deemphasized and renamed: a 2007-12-28 08:31 AndyArmstrong

Submitted by AndyArmstrong on 2007.12.28 8:31
AndyArmstrong writes "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.

"

  HTTP::Proxy::GreaseMonkey 2007-12-16 15:11 AndyArmstrong

Submitted by AndyArmstrong on 2007.12.16 15:11
Yesterday I posted a GreaseMonkey script to add a CPAN Dependencies link to search.cpan.org.

The only problem with that is that FireFox is not my main browser. I tend to use FireFox for web development (FireBug++) and Safari for general surfing. Theoretically you can use GreaseMonkey scripts in Safari using CreamMonkey - but I couldn't get that to play nicely with Leopard.

So I've released HTTP::Proxy::GreaseMonkey which builds on BooK's excellent HTTP::Proxy to provide a local proxy that functions like GreaseMonkey.

Version 0.01 of HTTP::Proxy::GreaseMonkey has no support for the GM_* utility functions that the real GreaseMonkey provides - but it works well enough to support my CPAN dependencies user script and probably quite a few other GM scripts. Suggestions are welcome. Suggestions with patches even more so.

  CPANdeps + Greasemonkey 2007-12-15 14:52 AndyArmstrong

Submitted by AndyArmstrong on 2007.12.15 14:52
I've just written a quick and dirty Greasemonkey script that adds a link to David Cantrell's excellent CPAN dependencies to any CPAN distribution's page on search.cpan.org.

// ==UserScript==
// @name           CPAN Search
// @namespace      http://hexten.net/
// @description    Add links to CPAN
// @include        http://search.cpan.org/
// ==/UserScript==

var new_links = {
    'CPAN Dependencies': function(url, name) {
        return 'http://cpandeps.cantrell.org.uk/?module='
            + escape(make_module_name(name));
    }
};

function canonical_url() {
    var permalink = document.getElementById('permalink');
    if (permalink) {
        return permalink.firstChild.href;
    }
    return '';
}

function trim_url(url) {
    return url.replace(/^http:\/\/[^\/]+\/[^\/]+\//, '').replace(/\/$/, '');
}

function make_module_name(dist_name) {
    return dist_name.replace(/-/, '::');
}

function add_links(nd) {
    var end = nd.lastChild;
    nd.removeChild(end);
    var dist_url  = canonical_url();
    var dist_name = trim_url(dist_url);
    // console.log(dist_name + ' ' + dist_url);
    var keys = [];
    for (var k in new_links) {
        keys.push(k);
    }
    keys = keys.sort();
    for (var l = 0; l < keys.length; l++) {
        nd.appendChild(document.createTextNode(" ]\n[ "));
        var name = keys[l];
        var link = document.createElement('A');
        link.href = new_links[name](dist_url, dist_name);
        link.innerHTML = name;
        nd.appendChild(link);
        // console.log(name + " " + link);

    }
    nd.appendChild(end);
}

var rows = document.getElementsByTagName('tr');
if (rows) {
    for (var r = 0; r < rows.length; r++) {
        var cells = rows[r].getElementsByTagName('td');
        if (cells.length == 2 && cells[0].innerHTML == 'Links') {
            add_links(cells[1].firstChild);
        }
    }
}

I'm sure the DOM walking can be improved - but it works. To add other links add them to the new_links hash. Each entry is the anchor text for the link and a function that returns the URL to link to.

  Test::Harness 3.00 2007-11-06 09:49 AndyArmstrong

Submitted by AndyArmstrong on 2007.11.06 9:49
We've just released Test::Harness 3.00. It's a complete rewrite of Test::Harness with a more modular architecture that should make it easier to write custom testing tools.

In no particular order here are some of the things that have changed:

  • Support for TAP version 13
  • Cleaner API
  • Closer integration with CPAN::Reporter
  • Parallel test runs
  • Improved output formatting
  • Machine readable YAML diagnostics
  • Better detection of TAP syntax errors

And in alphabetical order some of the people who made it happen:

  • Sebastien Aperghis-Tramoni
  • Leif Eriksen
  • Shlomi Fish
  • David Golden
  • Jim Keenan
  • Andy Lester
  • Michael Peters
  • Curtis Ovid Poe
  • Michael Schwern
  • Gabor Szabo
  • Eric Wilhelm

Thanks!

Development on Test::Harness continues. There are a number of proposals on the Test Anything Wiki and at least some of them will make it into future releases. If you'd like to follow progress more closely - or offer some help - you'll find the Test::Harness developers on the TAPX-DEV mailing list or on #toolchain on IRC.

  Leopard's tar is broken 2007-11-01 18:06 AndyArmstrong

Submitted by AndyArmstrong on 2007.11.01 18:06
I've just upgraded my MBP to Leopard. Apple's version of tar has the annoying habit of generating extra files to represent Mac specific attributes. That's particularly annoying for CPAN authors because they tend to break your test suite and you can't easily see them without unpacking the archive on a non-Mac system. Grrr.

It used to be possible to disable this behaviour by setting the env var COPY_EXTENDED_ATTRIBUTES_DISABLE to some true value - but this seems to have stopped working in Leopard. As a result I've just released a broken version of Captcha::reCAPTCHA. Double Grrr.

strings /usr/bin/tar fails to reveal anything promising, /usr/bin/gnutar is just a hard link to /usr/bin/tar and I can't get the MacPorts gnutar to build so for now I've restored a copy of Tiger's tar from a backup and dumped it in ~/bin (which I have on my path). Phew.

Watch out Mac-based module authors - it's hard to detect that you have a broken archive without testing it on a non-Mac machine.

  Leopard's tar is broken 2007-11-01 18:06

Journal by AndyArmstrong on 2007.11.01 18:06

I've just upgraded my MBP to Leopard. Apple's version of tar has the annoying habit of generating extra files to represent Mac specific attributes. That's particularly annoying for CPAN authors because they tend to break your test suite and you can't easily see them without unpacking the archive on a non-Mac system. Grrr.

It used to be possible to disable this behaviour by setting the env var COPY_EXTENDED_ATTRIBUTES_DISABLE to some true value - but this seems to have stopped working in Leopard. As a result I've just released a broken version of Captcha::reCAPTCHA. Double Grrr.

strings /usr/bin/tar fails to reveal anything promising, /usr/bin/gnutar is just a hard link to /usr/bin/tar and I can't get the MacPorts gnutar to build so for now I've restored a copy of Tiger's tar from a backup and dumped it in ~/bin (which I have on my path). Phew.

Watch out Mac-based module authors - it's hard to detect that you have a broken archive without testing it on a non-Mac machine.

  Testing on VMS 2007-11-01 16:30 AndyArmstrong

Submitted by AndyArmstrong on 2007.11.01 16:30
AndyArmstrong writes "As previously reported progress on Test::Harness 3.00 ran aground temporarily while we worked out how to run our test suite on VMS. We're back on track now, running our smoke tests automatically on a VMS TestDrive account.

With help from Craig Berry and Michael Lemke I've put together a page on the Perl-QA Wiki that describes the process:

http://perl-qa.hexten.net/wiki/index.php/Testing_on_VMS

It includes a link to the script we use to remotely execute our test suite. If I've missed anything important or made any errors please feel free to dive in and fix them.

"

  Testing on VMS 2007-11-01 16:30

Journal by AndyArmstrong on 2007.11.01 16:30

As previously reported progress on Test::Harness 3.00 ran aground temporarily while we worked out how to run our test suite on VMS. We're back on track now, running our smoke tests automatically on a VMS TestDrive account.

With help from Craig Berry and Michael Lemke I've put together a page on the Perl-QA Wiki that describes the process:

http://perl-qa.hexten.net/wiki/index.php/Testing_on_VMS

It includes a link to the script we use to remotely execute our test suite. If I've missed anything important or made any errors please feel free to dive in and fix them.

  Perl Flavoured Google 2007-10-22 08:58 AndyArmstrong

Submitted by AndyArmstrong on 2007.10.22 8:58
For the last few months I've been using a couple of Perl specific Google Co-op searches.

The Perl search pulls results from 72 assorted Perl related sites including CPAN and perldoc.perl.org. It tends to work for those questions that you're not even sure where to ask.

Perhaps more useful is the CPAN search which I find often outperforms search.cpan.org. In particular it finds 'one word' module names like CGI or FCGI both of which search.cpan.org currently overlooks.

If you have any suggestions for sites I've missed or other improvements give me a shout.