On Sat Sep 26 05:21:35 2015, JV wrote:
Show quoted text> Isn't the actual problem the use of the ":s" specifier? AFAIK, GNU
> getopt only knows options that either take an argument, or not take an
> argument.
>
> This would mean that the gnu_getopt config setting for Getopt::Long
> would disable most of its interesting features, limiting itself to the
> very basic set that GNU getopt supports. I doubt that would be a
> welcomed change.
>
> I think it will be better to change the documentation that the
> gnu_getopt config setting will emulate the GNU getopt behaviour to a
> limited but useful extent.
No, that's not the behavior as I understand it. The processing as described in Mark's earlier post is what I've seen to be the usual, unsurprising behavior.
For mandatory arguments (eg, '=s'), the behavior should be as currently written, eg, an optional equal sign with consumption of the next token as the option's argument. That token may be the split off `$optarg` portion or the next argument in the array/string. But for optional arguments (eg, ':s'), if an argument is supplied for the option, it must be signaled by an equal sign. No equal sign means no argument.
From "
http://linux.die.net/man/1/getopt", "If the option has an optional argument, it must be written directly after the long option name, separated by '=', if present".
This creates the behavior noted in the first post, so that neither `app --foo=x bar` nor `app --foo bar` consumes bar as foo's argument. Again, this is the general behavior that I've seen and come to expect. The consumption of bar as foo's argument in the second case is surprising, as is the resultant need to use `app --foo= bar` to avoid bar's consumption. I don't think fixing this causes any harm to the usefulness of the module, whether in `gnu_compat` mode or not.
Here is a simple change that fixes the behavior without disabling any functionality and passes all tests... I think it's the better solution, although I don't know the code well enough to say that passing all tests is sufficient to certify the patch.
diff for `lib/Getopt/Long.pm`:
====<cut>
@@ -1109,9 +1109,8 @@ sub FindOption ($$$$$) {
my $mand = $ctl->[CTL_AMIN];
# Check if there is an option argument available.
- if ( $gnu_compat && defined $optarg && $optarg eq '' ) {
- return (1, $opt, $ctl, $type eq 's' ? '' : 0) ;#unless $mand;
- $optarg = 0 unless $type eq 's';
+ if ( $gnu_compat && (( defined $optarg && $optarg eq '' ) || not $mand ) ) {
+ return (1, $opt, $ctl, $type eq 's' ? '' : 0) ;#unless $mand;
}
# Check if there is an option argument available.
====<cut>
- Roy