I'm trying to make a function for a module accept optional arguments in the form of:
function(arg1, optional1 => opt1, optional2 => opt2, ..);
Yet I can't find anywhere that shows a good explanation how to do this. I came up with the following solution to accept email
, alpha
and html
arguments, but it's extremely convoluted and I can't believe there isn't a shorter way to accomplish this:
sub test
{
my ($s, @args) = @_;
my $alpha = 1;
my $html = 0;
my $email = 0;
for(my $i = 0; $i < scalar(@args); $i++)
{
if($args[$i] eq "alpha")
{
$i++;
$alpha = $args[$i];
}
elsif($args[$i] eq "email")
{
$i++;
$email = $args[$i];
}
elsif($args[$i] eq "html")
{
$i++;
$html = $args[$i];
}
}
return ($alpha, $email, $html);
}
my ($a, $b, $c) = test("stuff", ndhgffs => 1, email => 1, alpha => 0);
print $a . $b . $c;
EDIT:
Thanks to the answer below and comments below that, this solved it:
sub test
{
my ($s, %opts) = @_;
my $email = $opts{'email'} // 0;
my $alpha = $opts{'alpha'} // 1;
my $html = $opts{'html'} // 0;
return ($alpha, $email, $html);
}
sub function {
my $arg1 = shift;
my $arg2 = shift;
my %opts = @_;
my $optional1 = delete($opts{$optional1});
my $optional2 = delete($opts{$optional2});
croak("Unrecognized parameters ".join(' ', keys(%opts))) if %opts;
...
}
or
sub function {
my ($arg1, $arg2, %opts) = @_;
my $optional1 = delete($opts{$optional1});
my $optional2 = delete($opts{$optional2});
croak("Unrecognized parameters ".join(' ', keys(%opts))) if %opts;
...
}
Notes:
If you don't want to bother checking for unrecognized options, you don't need delete
.
You can easily assign default values when an argument is omitted or undef using
my $arg = delete($opts{$arg}) // 'default'; # Perl 5.10+