While working on issue #1 ("hash-storage" support), I stumbled upon an independent problem.
In fact, it seems like GLM (Getopt::Long::More) had already a bug for the case of mixing implicit/explicit handlers, i.e. "linkages" as GoL (Getopt::Long) calls them.
Note that this issue may first seem of minor importance, given that using GLOBAL variables has long fallen out of fashion, but since the bug would also cripple proper support of the hash-storage" mode (which reflects a more popular GoL usage pattern), it proves to be quite a hurdle for GoL => GLM migration path.
STEPS TO REPRODUCE
The following code snippet demonstrates the problem more concretely:
The above snippet does NOT work on v0.004 or current MASTER .
Instead, it results in the death of the underlying GoL (), with the following message 👎
Invalid option linkage for "baz=s
Note that although it happens to be GoL that ultimately dies, the problem appears to lie within GLM, and in particular in its naive expectation that the arguments to Getoptions would always come in pairs (optspec => handler); which is not necessarily the case in real life GoL usage.
EXPECTED RESULT
The above test snippet should not cause GoL/GLM to die.
Instead, GoL should just be falling back to its usual default (implicit) handling for those options where no explicit handlers are given, i.e. in our case : flag1, flag2, flag3.
In the absence of any hash-storage mode, like in this particular example, the associated implicit handling happens be populating the corresponding GLOBAL variables ($flag1, $flag2, $flag3), as if we had written the following snippet:
GoL happily accepts this particular usage pattern, as can be verified with the following equivalent snippet 👍
use Getopt::Long;
my $opts = {};
my $res = GetOptions(
'flag1|1',
'flag2|f',
'bool|b!' => \$opts{bool},
'int=i' => sub { $opts{int } = $_[1] ),
'flag3|k',
'module|M=s@' => sub { $opts{module } = $_[1] ),
);
Note that, since GoL does not itself recognize OptSpec objects, this snippet simulates the situation by replacing those with equivalent subroutine handlers, just to demonstrate the case.
The CULPRIT :-)
As mentioned above, the problem appears to arise from GLM's naive expectation that the arguments to Getoptions would always come in pairs (optspec => handler); which is not necessarily the case in real life (documented) GoL usage.
PROPOSED SOLUTION
I have a proposed solution which involves dropping reliance on systematic pairwise (% 2) processing of the arguments passed to Getopts* and friends. It will be packaged in the upcoming PR.
The code changes are actually within the GetoptsFromArray function,.
While working on issue #1 ("hash-storage" support), I stumbled upon an independent problem.
In fact, it seems like GLM (
Getopt::Long::More
) had already a bug for the case of mixing implicit/explicit handlers, i.e. "linkages" as GoL (Getopt::Long
) calls them.Note that this issue may first seem of minor importance, given that using GLOBAL variables has long fallen out of fashion, but since the bug would also cripple proper support of the hash-storage" mode (which reflects a more popular GoL usage pattern), it proves to be quite a hurdle for GoL => GLM migration path.
STEPS TO REPRODUCE
The following code snippet demonstrates the problem more concretely:
CURRENT (FAILING) MODE
The above snippet does NOT work on v0.004 or current MASTER .
Instead, it results in the death of the underlying GoL (), with the following message 👎
Note that although it happens to be GoL that ultimately dies, the problem appears to lie within GLM, and in particular in its naive expectation that the arguments to Getoptions would always come in pairs (optspec => handler); which is not necessarily the case in real life GoL usage.
EXPECTED RESULT
The above test snippet should not cause GoL/GLM to die.
Instead, GoL should just be falling back to its usual default (implicit) handling for those options where no explicit handlers are given, i.e. in our case : flag1, flag2, flag3.
In the absence of any hash-storage mode, like in this particular example, the associated implicit handling happens be populating the corresponding GLOBAL variables ($flag1, $flag2, $flag3), as if we had written the following snippet:
VANILLA GoL BEHAVIOUR (without GLM)
GoL happily accepts this particular usage pattern, as can be verified with the following equivalent snippet 👍
Note that, since GoL does not itself recognize OptSpec objects, this snippet simulates the situation by replacing those with equivalent subroutine handlers, just to demonstrate the case.
The CULPRIT :-)
As mentioned above, the problem appears to arise from GLM's naive expectation that the arguments to Getoptions would always come in pairs (optspec => handler); which is not necessarily the case in real life (documented) GoL usage.
PROPOSED SOLUTION
I have a proposed solution which involves dropping reliance on systematic pairwise (% 2) processing of the arguments passed to Getopts* and friends. It will be packaged in the upcoming PR.
The code changes are actually within the GetoptsFromArray function,.