Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

How can I have both short and long options with Getopt::Long?

by Anonymous Monk
on Nov 12, 2009 at 11:48 UTC ( [id://806698]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have been reading the documentation for Getopt::Long but I can't find a way to do what I would like to achive.

Let's restrict it to one option only: verbose. What I would like is to be able to use -v or --verbose only. So -verbose and --verb would both be wrong.

The main code is:

use Getopt::Long; my $verbose=''; GetOptions ( 'verbose' => \$verbose );

However, that accepts -V also. So I change it to

use Getopt::Long qw{:config no_ignore_case};

So far so good, but now --v or -ver both work. I thought I could use bundling like

use Getopt::Long qw{:config bundling no_ignore_case};

but it doesn't quite do what I had in mind.

If I use -ver it correctly says

Unknown option: e Unknown option: r

But if I use --verb (note the double dash) it still recongnises it, which I don't want.

To summarize: if there is one dash then only v is accepted and any other letter should be reported as an 'Unknown option'; if there are two dashes then only the full 'verbose' should be accepted. How can I achive that?

Thanks

Replies are listed 'Best First'.
Re: How can I have both short and long options with Getopt::Long?
by 7stud (Deacon) on Nov 12, 2009 at 13:00 UTC

    This works for me:

    $ cat 3perl.pl use strict; use warnings; use 5.010; use Getopt::Long; Getopt::Long::Configure(qw{no_auto_abbrev no_ignore_case_always}); my $verbose = ""; GetOptions ('verbose|v' => \$verbose); say $verbose;
    $ perl 3perl.pl -v 1 $ perl 3perl.pl -V Unknown option: V $ perl 3perl.pl -verbose 1 $ perl 3perl.pl -Verbose Unknown option: Verbose $ perl 3perl.pl -ver Unknown option: ver

      If I'm understanding the OP correctly, those two cases should be considered an error, too:

      $ ./806698.pl -verbose 1 $ ./806698.pl --v 1

      (the former case could be solved with bundling, but the latter would then still be accepted)

      Some more:

      $ perl 3perl.pl --verbose 1 $ perl 3perl.pl --Verbose Unknown option: Verbose $ perl 3perl.pl --ver Unknown option: ver
Re: How can I have both short and long options with Getopt::Long?
by bellaire (Hermit) on Nov 12, 2009 at 13:31 UTC

    It doesn't look like you can do exactly what you want. You can turn use no_auto_abbrev as others have noted and specify 'v|verbose' as your option, but this will allow '--v', which you explicitly stated you don't want.

    I think that's as close as you can get, since although bundling will not allow long options with a single dash, there is no similar option that disables abbreviated options with a double dash.

      Thanks everyone. If using bundling, no_ignore_case and no_auto_abbrev is the closest I can get than, well, it's the closest I can get.

Re: How can I have both short and long options with Getopt::Long?
by happy.barney (Friar) on Nov 12, 2009 at 13:02 UTC
    use Getopt::Long qw{ :config bundling no_ignore_case no_auto_abbrev};
Re: How can I have both short and long options with Getopt::Long?
by ikegami (Patriarch) on Nov 12, 2009 at 15:54 UTC
    use strict; use warnings; use Getopt::Long qw( :config posix_default bundling no_ignore_case ); GetOptions('verbose|v' => \my $opt_verbose) or die("usage\n"); print( $opt_verbose || 0, "\n");

    The ones that should work:

    >perl 806754.pl -v 1 >perl 806754.pl --verbose 1

    The ones that shouldn't work:

    >perl 806754.pl -verbose Unknown option: e Unknown option: r Unknown option: b Unknown option: o Unknown option: s Unknown option: e usage >perl 806754.pl --verb Unknown option: verb usage >perl 806754.pl -V Unknown option: V usage >perl 806754.pl --Verbose Unknown option: Verbose usage

    6 of 6 tests successful.

      --v still fails to fail  (as requested, "if there are two dashes then only the full 'verbose' should be accepted") — as with the other variants already suggested.

        Missed that. There's no way around it because Getopt::Long has no way of knowing "v" shouldn't be considered a full option name. Honestly, that shouldn't be an issue.
      >perl 806754.pl --v you code is working in above case (it's need to show error, but that is not happening here)
Re: How can I have both short and long options with Getopt::Long?
by 7stud (Deacon) on Nov 12, 2009 at 16:54 UTC

    How about rolling your own?

    use strict; use warnings; use 5.010; my %ok = qw{-v 1 --verbose 1}; my $verbose = ""; for (@ARGV) { $ok{$_} ? $verbose=1 : say "Unknown option: $_"; } say $verbose --output:-- $ perl 1perl.pl -v 1 $ perl 1perl.pl --verbose 1 $ perl 1perl.pl -V Unknown option: -V $ perl 1perl.pl --v Unknown option: --v
Re: How can I have both short and long options with Getopt::Long?
by bigj (Monk) on Apr 16, 2014 at 13:26 UTC
    As long as you don't plan much special stuff, I'd usually recommend a module like App::Cmd that just takes all the usual stuff away from you. IMHO, Getopt::Long is to App::Cmd like CGI to a modern framework like Dancer or Molijious unless you plan something really special.

    Greetings,
    Janek Schleicher

      Ugh - reading the documentation of App::Cmd, it feels far more like Catalyst when compared to CGI or Dancer.

      It expects your application to have subcommands and wants you to create a subclass for every subcommand. It automagically loads plugins and hides the real structure of the program from somebody who just wants to look at how a program does its stuff.

      This approach certainly makes sense if your program is basically the gateway to a lot of subcommands, like git is the dispatcher to a large family of other programs. But most programs never reach that scale, and below that scale, the approach of App::Cmd strikes me as conceptual overkill.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://806698]
Approved by almut
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-24 02:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found