This isn't perfect, but I find it convenient.
use Getopt::Long; %opt_ctl = ( "recipient_of_message|r=s@", \@recips, # "URLs_to_use|u=s@", \@urls_in, "do_all_VIPs_except_those_expected_down|a!", \$all, "do_all_VIPs_without_excepotions|awe!", \$awe, "timeout_for_gets|t=i", \$timeout, "show_usage|h!", \$sho_usag +e, "debug|d=i", \$debug, "select_this_proxy_-_1_or_3_or_user_specified|p=s", \$proxy_sel, "smtp_server|s=s", \$smtpsrvr, "time_between_cycles|w=i", \$wait, "no_mail_sent_ever|nm!", \$no_mail, "no_proxy|np!", \$no_proxy, ); Getopt::Long::Configure( qw(no_auto_abbrev) ); $debug = 0; if ( not GetOptions(%opt_ctl) or $sho_usage ) { usage() } sub usage { (@f, %switch, $out, ) = ( ); # $out = "\nUsage:\n\n$0 [ -t timeout ] [ -p 1 | -p 3 | -p proxy_U +RL] [ -e ] [ -a ] [ -d ] [ -w wait ]\n"; #self-document switch options for ( keys %opt_ctl ) { @f = split(/\||=|!/); $switch{$f[1]} = $f[0]; } for ( sort keys %switch ) { $def = $switch{$_}; $def =~ s/\_/ /g; $_ = '-' . $_; $out .= sprintf "%4s: %s\n", $_, $def; } print "$out\n"; exit; }

Replies are listed 'Best First'.
Re: "self documenting" switch options
by halley (Prior) on Jul 27, 2003 at 03:21 UTC

    Why stunt the capabilities of getopt by shoehorning in other kinds of information in its switch strings?

    In such cases, I usually just make a more complex structure which associates getopt switches to arrays which contain variables, help texts, validator functions and whatever else. Then I just map out the elements that Getopt::Long expects. For --help, I can also look at the switch strings and other clues to automate some of the messages for consistency.

    This code is a sketch from memory. There are other structures that would do just as well.

    my $Verbose; my $Secret; %Options = { 'verbose+' => [ \$Verbose, "Makes the output more verbose." ], 'secret!' => [ \$Secret, "Enables secret features." ], }; ... sub usage { ... foreach my $option (sort keys %Options) { my $switch = $option; $switch =~ s/=.*$//; $switch =~ s/\W*$//; $message = $Options{$option}[1]; $message .= " Adding $switch increases the effect." if $option =~ /\+$/; $message .= " Use --no$switch to disable." if $option =~ /\!$/; print Wrap(undef, undef, "$switch: $message"), $/; } ... GetOptions(map { $_, $Options{$_}[0] } keys %Options);

    (One should mention the POD::Usage here, but I find it a little stiff, personally.)

    --
    [ e d @ h a l l e y . c c ]

      Why stunt the capabilities of getopt by shoehorning in other kinds of information in its switch strings?

      Because I never use the long option names and this lets me have it all in 1 place, so it's almost impossible to forget to document the option. As I said previously, not perfect, but convenient.

      Update: I'm going to stop posting when my caffeine level is low. Your solutions does keep it all in once place, without imposing limitations on the descriptions as I had to. I'll probably start using your method for future work. You should post yours as a snippet.

      Your solution also illustrates something I've heard elsewhere and found invaluable: "complicated data structures are better than complicated code". Or maybe it was "better data structures make better code". Whatever it was, your example has more of it than mine.

      --Bob Niederman, http://bob-n.com
Re: "self documenting" switch options
by rob_au (Abbot) on Jul 27, 2003 at 06:02 UTC