Five percent of indexed CPAN packages come from just two distributions

And both have to do with advertising.

Counting all packages indexed in 02packages.details.txt (possibly across multiple tarball versions), two distributions account for 5% of CPAN packages:

  • Microsoft-AdCenter

Here are the top 10 with the number of index lines each:

Microsoft-AdCenter: 1628
Shipment: 1197
eBay-API: 1160
BioPerl: 851
Graphics-VTK: 707
DateTime-Locale: 469
Net-Amazon: 455
UMMF: 451
Locales: 426

Together they account for 8.6% of the 135,000 or so currently indexed packages.

Posted in perl programming | Tagged , , , | Comments closed


I've been looking at patterns of $VERSION definition in the wild. And, wow. There's some crazy stuff out there.

Remember that the way PAUSE (and other tools) parse a $VERSION definition line is not by loading the module, but by extracting it as a standalone line and essentially running it through eval. PAUSE says this must work:

perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' path/to/

PAUSE actually does something more sophisticated and safe, but if parse_version works, so will PAUSE.

Keeping that in mind, listed below are some of the more surprising/amusing/horrifying things I've seen. Not all are broken, but even the ones that work are, well, unusual.

I'm not naming any names — and I'll obscure them if it would be too revealing — but these are all from real .pm files in tarballs currently indexed on CPAN.

$VERSION = '';

$VERSION = '0.O1';

$VERSION = "0.01c";


$VERSION = '0.10E0';

our $VERSION = -722;

my $VERSION = '0.01';

$VERSION = 0xdeadbeef;

our $VERSION = '1.0-1';

$VERSION = 2006_08_16.1;

our $VERSION = '0.8.1-2';

$VERSION = $VERSION = "0.1";

$Foo::Bar::VERSION |= '2.6';

my $VERSION = 'OMG-04-05-01';

our $VERSION = '1.4.A8UG1gG';

our $VERSION = 'set-when-loading';

our $VERSION = '$Revision: 1.2 $';

our $VERSION = $Foo::Bar::VERISON;

our $VERSION=$Foo::VERSION; use Foo;

local $Other::Module::VERSION = 666;

$Foo::Bar::VERSION="1.23" unless $Foo::Bar::VERSION;

$Foo::Bar::VERSION='1.00' unless $INC{'Foo/'};

$VERSION=eval 'use version;1' ? 'version'->new('0.33') : '0.33';

Some of these are so nuts that unless they are modified by a subsequent line into a standard version format, then a version check will throw an error on any recent perl:

package Foo;
our $VERSION = "1.2-trailing-junk";
$ perl -I. -we 'use Foo 0;'
Invalid version format (non-numeric data) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

Moral of this story: make sure your $VERSION definition parses cleanly on a line by itself and make sure it's a valid version number. If you're not sure, check it with the is_lax function from

Posted in perl programming | Tagged , , | Comments closed

Previewing POD before shipping

I always find typos after I ship to CPAN.

There is something about reading my docs in nicely-formatted HTML on a web site that makes my mistakes jump out at me. And then I feel stupid for not having caught it earlier.

I used to use the pod renderer to preview my POD, but I stopped after a while, probably when I stopped using for everything else as well.

What I really wanted was something local, quick and pretty. So I ripped off a bit of what MetaCPAN was doing to render POD and came up with my own utility program: podpreview.

$ podpreview path/to/

That renders the POD from the file into HTML with an embedded stylesheet, saves it in a temporary file and opens up that file in my browser. There I can happily proofread and find my typos before shipping.

If you'd like to try it out and adapt it to your own style, here it is:

#!/usr/bin/env perl
use v5.10;
use strict;
use warnings;
use Browser::Open qw/open_browser/;
use Path::Tiny;
use Pod::Simple::XHTML;

my $file = shift @ARGV
  or die "Usage: $0 <file>";
$file = path($file);

my $psx = Pod::Simple::XHTML->new;
$psx->output_string( \my $html );
$psx->html_header( my_header() );
$psx->html_footer( my_footer() );
$psx->parse_string_document( $file->slurp_utf8 );

my $temp = path( $ENV{TMPDIR}, 'podpreview', $file->relative . '.html' );

sub my_css {
    return <<'CSS';
body { background: snow; font-family: sans-serif; }
div#main { width: 70%; margin: 5% auto; }
h1 { font-size: 1.5em; margin: .83em 0 }
h2 { font-size: 1.17em; margin: 1em 0 }
h3 { margin: 1.33em 0 }
h4 { font-size: .83em; line-height: 1.17em; margin: 1.67em 0 }
h5 { font-size: .67em; margin: 2.33em 0 }
h1, h2, h3, h4, h5 { font-weight: bolder; color: #36c }
a:link { color: #36c }
code { font-size: 1.2em }

sub my_header {
    my $css = my_css();
    return <<"HEADER";
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<div id="main">

sub my_footer {
    return <<'FOOTER';
Posted in perl programming | Tagged , , | Comments closed

How do you manage your DarkPAN?

Hi, folks.

I'm doing research for a talk about how people manage and deploy proprietary Perl code and CPAN code and how they manage their dependency chains over time.

If your current (or past) company does something you think is particularly good (or bad!), I'd love to swap emails or do a 15 or 20 minute phone call with you. (You and/or your company can be anonymous in the final talk if you desire.)

Please email me at "dagolden" at "CPAN dot org" if you're willing to share.

Thank you very much!


Posted in perl programming | Tagged , , | Comments closed

Nothing to see here

This is a test to see if the ironman feed is picking up this category/tag.

Posted in devops | Tagged , | Comments closed

© 2009-2014 David Golden All Rights Reserved