I'm trying to write a program that has an option that takes an
optional argument, in such a way that it accepts options in the same
fashion with the exact same behavior as perl -i or git --color. Unfortunately
Getopt::Long doesn't exactly work that way and I can't get it to. Allow me to explain.
Example #1: If you run perl -i .bak, it does not use .bak as a backup file
extension for editing in-place, as perl -i.bak would.
Example #2: If you run git diff --color always, it does not specify always for
the --color option; for that you must use --color=always.
I call that "non-greedy".
I cannot figure out how to configure Getopt::Long to handle this
scenario similarly. Programs using it behave "greedy" in this regard.
Consider the following program:
#!/usr/bin/env perl
use warnings;
use strict;
use Getopt::Long;
our $color;
our $backup;
Getopt::Long::Configure(qw(no_bundling));
Getopt::Long::GetOptions(
"color:s" => \$color,
"i:s" => \$backup,
) or die(":-(\n");
printf("\$color = '%s'\n", $color // '(undef)');
printf("\$backup = '%s'\n", $backup // '(undef)');
printf("\@ARGV = '%s'\n", join(', ', @ARGV));
and the following invocation, for example:
./foo.pl -i .bak --color always meow moo
Desired behavior:
$ ./foo.pl -i .bak --color always meow moo
$color = ''
$backup = ''
@ARGV = .bak, always, meow, moo
Actual behavior:
$ ./foo.pl -i .bak --color always meow moo
$color = 'always'
$backup = '.bak'
@ARGV = meow, moo
As a workaround, you can use the option terminator
--.