Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

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

by ysth (Canon)
on May 19, 2008 at 05:39 UTC ( #687283=perlmeditation: print w/ replies, xml ) Need Help??

Tom Christiansen wrote a piece on p5p today advocating for Getopt::Long use.

Some excerpts:

I *really* like Getopt::Long...I cannot say enough good things about it to do it the justice it deserves... The only problem is that I just don't use it enough. I bet I'm not alone. 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.

Comment on Use Getopt::Long even if you don't think you need to
Re: Use Getopt::Long even if you don't think you need to
by almut (Canon) on May 19, 2008 at 08:12 UTC

    Yes, I have to admit I also occasionally had hand-hacked parsing for those one or two options. In the meantime, I've learned from those mistakes, i.e. I use Getopt::Long as soon as the first option idea pops up in my mind... because I know it won't be the last. Not only is it less work, it's also so much more flexible and DWIM.

    On the other hand, I'd say it's never too late. And, as any option parsing is typically done in some central place anyway (rather than being scattered all over the program), replacing it with Getopt::Long has usually been a matter of less than five minutes — unless you postpone that decision until your tool has as many options as gcc...

      I love having long options because it provides a better description of what the options are when someone views your program for the first time. It simply is a great user interface tool when someone comes across on of your scripts for the first time.

      I start every new command line perl script with this template...

      #!/usr/bin/perl use strict; use warnings; use Getopt::Long; use Pod::Usage; Getopt::Long::Configure("no_ignore_case"); GetOptions( 'h|help'=> sub { pod2usage( { -verbose => 1, -input => \*DATA } ); exit; +}, 'H|man' => sub { pod2usage( { -verbose => 2, -input => \*DATA } ); exit; +}, ); __DATA__ head1 NAME =head1 SYNOPSIS Options: -h --help Display this help -H --man Display detailed help (examples) =head1 EXAMPLES =head2 First Example...

      -biz-

Re: Use Getopt::Long even if you don't think you need to
by BrowserUk (Pope) on May 19, 2008 at 08:36 UTC

      It's always easy to criticise (at least I sense some criticism in your post :) ... but I'm wondering what alternative user interface you would suggest if you want that functionality? Some config file, or even a GUI (*shudder*), or what else?  Not wanting to start a flame war, but I think command line options aren't that bad after all, provided they come with reasonably accessible documentation and have sensible defaults, so you'd only need a few of them anyway in most cases.

        When things get complex like that I think a config file should be an option and a GUI to help manage it might also be nice.

        But keep in mind you can always put everything into a shell script with each option on its own line (just use a backslash to continue the command on the next line). In effect the shell script then becomes a config file (albeit a weak one).

      Thats perfectly simple / clear for the target audience

      Mmm, and apart from a huge waste of space, your point is?

      • another intruder with the mooring in the heart of the Perl

        Command line interfaces are like bicycles.

        Simple, Economical. Lightweight; requiring little by way of supporting infrastructure or resources(*). Easy to learn, use and maintain.

        (*)Contrast with the need for gas and gas stations, and tankers and refineries et al., for motorbikes, cars, busses, trucks etc.

        But like the bicycle, every now and again there is the need to carry a little something along with you. So you think to add a saddle bag or maybe a rack and panniers. But whilst you're in the shop looking at what's available, some enthusiast suggests that these options are far too limiting and that once you have either you'll soon be needing something more.

        Of course, the trouble with that is, once you have it, there is the temptation to use it for everything until eventually someone will ask if there isn't a better way?

        And before anyone sniggers to themselves, "he just wants a GUI", is the fact that they consider that the only alternative, a limitation of my imagination, or theirs?

        Futurism, like featurism, tends to open the door to complexity and bloat. Sometimes, actually quite often, using just as much as you need now, besides keeping things simple for now, has the secondary effect of constraining future complexity by forcing the question: What do we actually need?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Use Getopt::Long even if you don't think you need to
by herveus (Parson) on May 19, 2008 at 12:11 UTC
    Howdy!

    I've taken to using Getopt::Euclid. It forces me to write POD in order to have arguments at all, then handles the option parsing for me.

    I suppose the main message is "don't be hand-rolling your option parser", just as "don't be hand-rolling your CGI parameter parser". Some things aren't worth the effort to reinvent save as a pedagogical exercise.

    yours,
    Michael

      I'd fallen in love with Getopt::Euclid myself. Unfortunately many of the programs I write must be distributed via Activestate's PerlApp which does not allow the program to see anything past it's __END__ tag.

      I've fallen back to using Getopt::Long and Pod::Usage because PerlApp programs can be made to see what's in their __DATA__ section.

Re: Use Getopt::Long even if you don't think you need to
by grinder (Bishop) on May 19, 2008 at 14:25 UTC

    I must say was rather surprised by that remark. It's worth spelling out in full:

    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; maybe like this:

    if (@ARGV && $ARGV[0] eq '-v') { $verbose = 1; shift @ARGV; }

    I couldn't believe anyone (still?) reasons this way. In the case of command-line arguments, I find this line of reasoning is unconscionable. Sooner or later, and likely sooner, there will be a second option, and at that point, if you don't refactor you have just doubled your technical debt.

    Similarly, Larry's remark about not using a Getopt::* library because it didn't seem worth the bother to load it in for just an opt or two to be a bad case of premature optimisation.

    I'm happy to cut them slack because twenty years ago, people didn't know any better :) But in this day and age there is absolutely NO reason for rolling your own command-line processing. Any more than no-one should be decoding CGI paramters manually.

    • another intruder with the mooring in the heart of the Perl

      It’s nothing to do with not knowing better, and much to do with the fact that 20 years ago computers were far more limited. Even today, in a script that generates submenus in my window manager’s root menu and is run every time I hover over the submenu item (and therefore needs to launch, run, and terminate instantly), I had to use Getopt::Std over Getopt::Long because the latter just plain doesn’t load fast enough. Similar concerns exist when writing CGI scripts, which is thankfully a genre in decline. Another related issue might be memory use – big modules eat more RAM just for being loaded.

      Put in context as an anachronism, Larry’s justification seems a lot less irresponsible.

      Makeshifts last the longest.

Re: Use Getopt::Long even if you don't think you need to
by metaperl (Curate) on May 19, 2008 at 17:01 UTC
    David Golden's Getopt::Lucid is awesome. And he is responsive to RT reports as well.
Re: Use Getopt::Long even if you don't think you need to
by mrfirmware (Initiate) on May 22, 2008 at 13:18 UTC
    You're right, Getopt::Long is great. However, I *do* use it all the time. I have a parse_cmdline_opt() sub that I use in all my Perl programs that takes ref to hash. To tailor the parser to each new program, I just change the hash keys for the options I wish to support. Everyone should use Getopt::Long, even for that one arg.
Re: Use Getopt::Long even if you don't think you need to
by petdance (Parson) on May 26, 2008 at 02:47 UTC
    Yes, yes, yes, a thousand times yes AND!!!

    Thou shalt always check the return value of GetOptions.

    I think ignoring the return code of GetOptions is even WORSE than ignoring the return code of open. 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.

    xoxo,
    Andy

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://687283]
Approved by andreas1234567
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2014-08-22 21:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (165 votes), past polls