In this application you can replace the given/when with a dispatch table. Other changes you can make since you use v5.36;:
- You no longer need use strict; -- this is implied by use v5.12; or above;
- You can use the experimental for-list syntax, though for the moment you will need to silence the "experimental" warning;
- You can either eliminate the no if ... or just disable the warnings for smartmatch unconditionally, depending on whether you use them elsewhere in your code.
The each() built-in is discouraged because there is only a single iterator for a given hash, which can be reset in un-obvious ways -- see the docs for each() for details.
My take on your boilerplate, with all the above incorporated, is:
#!/usr/bin/env perl
use v5.36; # was 'use 5.010;'
#use warnings; # unnecessary now!
#use strict; # unnecessary since 5.12.
no warnings 'experimental::for_list';
#no if $] >= 5.018, warnings =< "experimental::smartmatch";
use Getopt::Std;
my %opts;
getopts( 'hvi:', \%opts ) or die "getopts failed\n";
my $verbose;
my $infile;
for my ( $k, $v ) ( %opts ) {
state $dispatch = {
h => sub { ...; },
v => sub { ++$verbose; },
i => sub { $infile = $_[1]; },
};
my $code = $dispatch->{$k}
or die "*** BUG: no handler for -$k.\n";
$code->( $k, $v );
}
Note that the subroutines in the dispatch table do not close over your loop variables, so you must pass them in explicitly.