Functions are used when you want to reuse a block of code. You call or invoke a function by its name and passing arguments if the functions accepts any.
In Perl, @_ contains a list of arguments that was passed to the function. This list will have scalars, arrays and hashes flattened into one.
The example below will show how to call a function and define a function. Note that only a scalar was passed to the function and $_[0] contains that value;
#!/usr/bin/perl
use strict;
use warnings;
my $price = 12.99;
calculate_total($price);
sub calculate_total
{
my $p = $_[0];
print "You must pay ", $p;
}
When you run the following script, Perl will give you a warning that says “Odd number of elements in hash assignment” and $d is undef. This is because the hash is greedy and gets all the values from @_.
#!/usr/bin/perl
use strict;
use warnings;
my %pizza = (plain => 9.99, pepperoni => 10.99);
my $drink = 3.99;
display_price(%pizza, $drink);
sub display_price
{
my (%p, $d) = @_;
foreach my $i (keys %p)
{
print $p{$i}, "\n";
}
print $d, "\n";
}
Instead, you will want to pass the scalar first and then the hash. This will produce what you expected.
#!/usr/bin/perl
use strict;
use warnings;
my %pizza = (plain => 9.99, pepperoni => 10.99);
my $drink = 3.99;
display_price($drink, %pizza);
sub display_price
{
my ($d, %p) = @_;
foreach my $i (keys %p)
{
print $p{$i}, "\n";
}
print $d, "\n";
}
This example demonstrates how hash references are passed to functions.
#!/usr/bin/perl
use strict;
use warnings;
my %pizza = ( plain => { medium => 7.99, large => 9.99},
pepperoni => { medium => 9.99, large => 10.99},
supreme => { medium => 10.99, large => 12.99},
veggie => { medium => 9.99, large => 10.99}
);
my %order = ( plain => { large => 2},
pepperoni => { large => 2}
);
calculate_total(\%pizza, \%order);
sub calculate_total
{
my ($p, $o) = @_;
my $total = 0;
foreach my $style (keys %$o) {
print "$style \n";
foreach my $size (keys %{ $o->{$style} }) {
my $pies = $o->{$style}{$size};
print "$size: $pies pies\n";
$total += ($p->{$style}{$size} * $pies);
}
}
print "Your total is ", $total, "\n";
}
If you want to return $total to the main, you will have to use a return statement inside the function.
return $total;