sub greet {
my ($name, $greeting) = @_; # arguments arrive in @_ (aliased to the caller's values)
$greeting //= 'Hello';
return "$greeting, $name!";
}
say greet('Ana');
say greet('Bo', 'Hi');
sub add_all {
my $total = 0;
$total += $_ for @_;
return $total; # the last evaluated expression is returned implicitly anyway
}
sub get_shift {
my $self = shift; # shift defaults to @_ inside a sub
my %args = (size => 10, @_); # named arguments via a hash with defaults
}
10.2 Signatures (Stable in 5.36)
use v5.36; # enables signatures (and disables the old prototype-like syntax in sub declarations)
sub greet($name, $greeting = 'Hello') {
return "$greeting, $name!";
}
sub log_msg($level, $msg, @extra) { # slurpy array
say "[$level] $msg @extra";
}
sub configure(%opts) { # slurpy hash
say "$_=$opts{$_}" for sort keys %opts;
}
sub ignore_second($first, $, $third) { # unnamed placeholder parameter
return $first + $third;
}
sub with_default_expr($x, $y = $x * 2) { $x + $y } # defaults can use earlier params
sub maybe($x //= 10) { $x } # //= and ||= defaults (5.38+): apply when undef/false is passed
greet('Ana');
# greet(); # dies: "Too few arguments for subroutine 'main::greet'"
10.3 Returning Values and Context
sub min_max(@nums) {
my @sorted = sort { $a <=> $b } @nums;
return ($sorted[0], $sorted[-1]); # return a list
}
my ($min, $max) = min_max(3, 1, 9);
sub get_items { return wantarray ? @items : \@items } # context-aware return
sub fail { return } # bare return: undef in scalar context, () in list context
10.4 Passing Arrays and Hashes
sub print_all($aref, $href) { # pass references to avoid flattening
say "Array: @$aref";
say "Hash keys: @{[ sort keys %$href ]}";
}
print_all(\@fruits, \%age);
10.5 Prototypes, Recursion and Named Subs
sub factorial($n) { $n <= 1 ? 1 : $n * factorial($n - 1) }
use feature 'current_sub'; # __SUB__ for anonymous recursion (5.16+)
my $fact = sub ($n) { $n <= 1 ? 1 : $n * __SUB__->($n - 1) };
sub mygrep :prototype(&@) { # prototypes affect parsing (block-taking subs), not argument checking
my ($code, @list) = @_;
return grep { $code->() } @list;
}
my @even = mygrep { $_ % 2 == 0 } 1..10;
&foo; # old style: calls foo with the current @_ (avoid unless you mean it)
goto &foo; # tail call: replaces the current sub (used in AUTOLOAD)