in reply to Re: Inconsistent behavior of Getopt::Std
in thread Inconsistent behavior of Getopt::Std

Not really, it's simply taking dd as the value of the -d option.
True. The code is pretty convoluted and is also very old. But the key logic can easily be improved adding less then a dosen of lines. Legacy code like built in help screen via option -help that nobody needs can be removed. The value of @EXPORT array is unclear and probably can be removed too (archaeological Perl). All useful functionality can be implemented in 40 lines or less. Here is my variant, which probably can be considerably improved as this idea of extracting $first and $rest via regex is open to review: they split at the fixed position.
#!/usr/bin/perl
use v5.10;
   use warnings;
   use strict 'subs';
   use feature 'state';
   use Getopt::Std;

   getopts('b:cd:',\%options);
   foreach $opt (keys(%options)) {
      if($options{$opt} eq '' ){
         say "$opt is set to ''";
      }else{
         say "$opt is set to $options{$opt}";
      }         
   }
   exit 0;
sub getopts
{
my ($argumentative,$hash)=@_;
my (@args,$first,$rest,$pos);
   @args = split( //, $argumentative );
   while(@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)$/s ){
      ($first,$rest) = ($1,$2);
      if (/^--$/) {	# early exit if --
         shift @ARGV;
         last;
      }
      $pos = index($argumentative,$first);
      if( $pos==-1) {
         warn("Undefined option -$first skipped without processing\n");
         shift(@ARGV);
         next;
      }
      if (defined($args$pos+1) and ($args$pos+1 eq ':')) {
         # option with parameters
         if( $rest eq ''){          
            unless( @ARGV ){
               warn("End of line reached for option -$first which requires argument\n");
               $$hash{$first}='';
               last;
           }
           if ( $ARGV[0] =~/^-/ ) {
               warn("Option -$first requires argument\n");
               $$hash{$first} = '';
           }else{
               $$hash{$first}=$ARGV[0];
               shift(@ARGV); # get next chunk
           }
         } else {
            if( ($first x length($rest)) eq $rest ){
               $$hash{$first} = length($rest)+1;
            }else{
               $$hash{$first}=$rest;
            }
            shift(@ARGV);
         }
      }else {
         $$hash{$first} = 1; # set the option
         if ($rest eq '') {
            shift(@ARGV);
         } else {
            $ARGV[0] = "-$rest"; # there can be other options without arguments after the first
         }
      }
   }
}

Here are two test runs:

[0]  # perl  Std2.pl  -c -b -ddd
Option -b requires argument
d is set to 3
c is set to 1
b is set to ''
 
[0]  # perl   Std2.pl  -c -ddd -b
End of line reached for option -b which requires argument
d is set to 3
c is set to 1
b is set to ''
  • Comment on Re^2: Inconsistent behavior of Getopt::Std

Replies are listed 'Best First'.
Re^3: Inconsistent behavior of Getopt::Std
by perlfan (Parson) on Aug 17, 2020 at 06:37 UTC
    >True. The code is pretty convoluted and is also very old. But the key logic can easily be improved adding less then a dosen of lines. Legacy code like built in help screen via option -help that nobody needs can be removed.

    Moving the goal post?

    >archaeological Perl

    Do you mean vestigial?

    >is open to review

    Might want to take that to GH. I wouldn't call comments you get here a code review.