• Use Getopt::Long even if you don't think you need to

    Note: This is a post from 2008 that I dug up that still applies today.

    There's a thread over on perlmonks talks about Tom Christiansen's assertion that you should use it, by default, even when you only have one command-line argument to parse:

    What seems to happen is that at first we just want to add--oh say for example JUST ONE, SINGLE LITTLE -v flag. Well, that's so easy enough to hand-hack, that of course we do so... But just like any other piece of software, these things all seem to have a way of overgrowing their original expectations... Getopt::Long is just *wonderful*, up--I believe--to any job you can come up with for it. Too often its absence means that I've in the long run made more work for myself--or others--by not having used it originally. [Emphasis mine -- Andy]

    I can't agree more. I don't care if you use Getopt::Long or Getopt::Declare or Getopt::Lucid or any of the other variants out there. You know know know that you're going to add more arguments down the road, so why not start out right?

    Yes, it can be tricky to get through all of its magic if you're unfamiliar with it, but it's pretty obvious when you see enough examples. Take a look at prove or ack for examples. mech-dump is pretty decent as an example as well:

    GetOptions(
        'user=s'        => \$user,
        'password=s'    => \$pass,
        forms           => sub { push( @actions, \&dump_forms ); },
        links           => sub { push( @actions, \&dump_links ); },
        images          => sub { push( @actions, \&dump_images ); },
        all             => sub { push( @actions, \&dump_forms, \&dump_links, \&dump_images ); },
        absolute        => \$absolute,
        'agent=s'       => \$agent,
        'agent-alias=s' => \$agent_alias,
        help            => sub { pod2usage(1); },
    ) or pod2usage(2);
    

    Where the value in the hashref is a variable reference, the value gets stored in there. Where it's a sub, that sub gets executed with the arguments passed in. That's the basics, and you don't have to worry about anything else. Your user can pass --abs instead of --absolute if it's unambiguous. You can have mandatory flags, as in agent=s, where --agent must take a string. On and on, it's probably got the functionality you need.

    One crucial reminder: You must check the return code of GetOptions. Otherwise, your program will carry on. If someone gives your program an invalid argument on the command-line, then you know that the program cannot possibly be running in the way the user intended. Your program must stop immediately.

    Not checking the return of GetOptions is as bad as not checking the return of open. In fact, I think I smell a new Perl::Critic policy....

  • ack 2.24 is released, speeding up common cases

    I've just uploaded a new version of ack, version 2.24, to the CPAN and posted it to beyondgrep.com.

    Read on →

  • Avoid the vagueness of dies_ok() in Test::Exception

    It's good to check that your code handles error conditions correctly, but dies_ok() in Test::Exception is too blunt an instrument to do it.

    Read on →

  • Dueling code wizardry is one of the things I love most about Perl

    At least week's Perl Conference, Damian Conway talked about some new magical awesomeness he created, as he so frequently does. It's Test::Expr, and it makes it easier to write tests:

    Read on →

  • Improve your test logs with simple distro diagnostics

    Automated module testing systems are becoming more and more common.  In addition to our long-serving CPAN Testers service, Perl authors can have their modules tested by Travis for Linux and Appveyor for Windows.  CPAN Testers tests each distribution uploaded to PAUSE, whereas Travis and Appveyor keep an eye on your GitHub account (or other services) and try testing after each push to the home repo.

    Read on →