sub#
Declare or define a subroutine.
sub is the keyword that introduces a subroutine. With a NAME and a
BLOCK it defines a named subroutine in the current package. Without
a BLOCK it is a forward declaration. Without a NAME it is an
anonymous sub expression that evaluates to a code reference —
sub { ... } is the only form of sub that is actually an
expression; the named forms are declarations and return nothing
useful.
Synopsis#
sub NAME BLOCK # named definition
sub NAME (PROTO) BLOCK # with prototype
sub NAME : ATTRS BLOCK # with attributes
sub NAME (PROTO) : ATTRS BLOCK # prototype + attributes
sub NAME; # forward declaration
sub NAME (PROTO); # forward with prototype
my $ref = sub BLOCK; # anonymous, returns code ref
my $ref = sub (PROTO) : ATTRS BLOCK; # anonymous with proto + attrs
use feature 'signatures';
sub NAME ($x, $y = 0, @rest) BLOCK # named with signature
my $ref = sub ($x, $y) BLOCK; # anonymous with signature
What you get back#
The named forms (sub NAME BLOCK, sub NAME (PROTO) BLOCK, etc.)
are declarations. They install the subroutine into the current
package’s symbol table at compile time and contribute nothing to the
surrounding expression. Writing my $x = sub foo { 1 }; is a common
mistake — that is two statements glued together, and $x is left
undefined.
The anonymous form sub BLOCK is an expression. It evaluates — at
the point the expression is reached at runtime, not at compile time —
to a code reference closing over the lexical variables in scope. The
same sub { ... } expression evaluated twice produces two distinct
code references that share nothing:
my @refs = map { sub { $_ } } 1..3; # three independent closures
Forward declarations (sub NAME; with no block) do nothing at runtime
and return nothing. Their purpose is to announce the name to the
parser so that later calls to it can parse without parentheses.
Global state it touches#
The current package (set by
package) determines the fully-qualified name of a named sub.sub foo { }insidepackage Acme;installsAcme::foo, notmain::foo.@_inside the body holds the argument list (aliased to the caller’s scalars, except when a signature is in effect — see Signatures below). Assigning to@_as a whole breaks the aliasing for the rest of the call.$_[N]elements are aliases to the caller’s scalars. Modifying$_[0]modifies the caller’s variable; passing a literal and then modifying$_[0]is a fatal error.wantarrayinside the body reflects the context the subroutine was called in.
Named definition#
sub greet {
my ($name) = @_;
return "Hello, $name";
}
print greet("world"), "\n"; # Hello, world
The body is compiled at compile time. The name is visible from that point in the file onward; forward references inside the same package work because Perl defers method-style and bareword calls.
Redefining a named sub at runtime (eval "sub foo { ... }" or a
second sub foo { } in the same package) replaces the previous
definition and emits a Subroutine foo redefined warning under
use warnings. Suppress it with no warnings 'redefine' for the
scope of the redefinition.
Anonymous sub and closures#
sub make_counter {
my $n = 0;
return sub { ++$n };
}
my $c = make_counter();
print $c->(), $c->(), $c->(), "\n"; # 123
The inner sub captures $n from its enclosing scope. Each call to
make_counter creates a fresh $n and a fresh closure over it.
my @doublers = map { my $k = $_; sub { $k * 2 } } 1..3;
print $doublers[2]->(), "\n"; # 6
Note the intermediate my $k = $_ — closures capture variables, not
values, and $_ is shared across the map iterations. Without the
copy, every closure would see the last value of $_.
Signatures#
With use feature 'signatures' (on by default under use v5.36 and
later), the parameter list appears between the name and the block, and
arguments are bound to lexical variables automatically:
use feature 'signatures';
sub add ($x, $y) { $x + $y }
sub greet ($name, $greeting = "Hello") {
return "$greeting, $name";
}
sub log_all ($level, @msgs) {
print "[$level] $_\n" for @msgs;
}
Signature forms:
$x— required positional parameter.$x = EXPR— optional positional with default;EXPRis evaluated each call when the argument is missing.$x = undef— optional, defaults toundef(useful for documenting that a slot is nullable rather than omitted).@rest/%rest— slurpy, consumes all remaining arguments.$/@/%— unnamed placeholder, asserts arity without binding a variable.
Calling with the wrong arity croaks: Too many arguments for subroutine
or Too few arguments for subroutine.
Under a signature, @_ still exists but accessing it is a warning
under use warnings 'experimental::args_array_with_signatures' in
earlier Perls and discouraged in 5.42. Use the signature variables
instead.
Prototypes#
sub mypush (\@@) {
my $aref = shift;
push @$aref, @_;
}
my @a = (1, 2);
mypush @a, 3, 4; # @a is now (1, 2, 3, 4)
Prototypes are a compile-time parser hint, not a type check. They
change how call sites are parsed: \@ in the prototype above forces
the first argument to be an array and passes a reference to it. See
prototype to inspect a sub’s prototype.
Prototypes do nothing when the sub is called via &name(...) or
through a code reference. If you want a signature, use
use feature 'signatures'; prototypes and signatures can coexist with
the :prototype(...) attribute:
use feature 'signatures';
sub each_pair :prototype(\@) ($aref) { ... }
Attributes#
Attributes appear after : and modify how the sub is compiled or
registered:
sub critical :lvalue { $state } # usable on the left of =
sub noop :method { } # marked as a method (for some tools)
Common core attributes: lvalue, method, prototype(...),
const. Modules like Attribute::Handlers
let a package define its own. Unknown attributes are a compile-time
error.
Forward declaration#
sub later; # announce the name
plan later(3); # now parses without parens
sub later { ... } # defined later in the file
A forward declaration is only useful to tell the parser that later
is a subroutine so that later ARG parses as a call rather than an
indirect-object construct or a comma expression. It is not required if
you call with parentheses.
Examples#
Named sub, explicit argument unpacking:
sub area {
my ($w, $h) = @_;
return $w * $h;
}
print area(3, 4), "\n"; # 12
Anonymous sub passed to a higher-order function:
my @lengths = map { sub { length shift } }->(@_),
("alpha", "beta", "gamma"); # not quite — see below
More useful: passing a sub directly:
use List::Util qw(first);
my $first_even = first { $_ % 2 == 0 } 1, 3, 4, 7; # 4
Implicit return — the value of the last expression is returned:
sub double { $_[0] * 2 } # no return needed
print double(21), "\n"; # 42
Context-sensitive return:
sub names {
my @n = qw(alice bob carol);
return wantarray ? @n : scalar @n;
}
my @all = names(); # ("alice","bob","carol")
my $n = names(); # 3
Modifying caller arguments via @_ aliasing:
sub upcase_in {
for (@_) { $_ = uc }
}
my $s = "hello";
upcase_in($s);
print $s, "\n"; # HELLO
Recursion with __SUB__ — a reference to the current sub
without naming it:
use feature 'current_sub';
my $fact = sub {
my $n = shift;
$n < 2 ? 1 : $n * __SUB__->($n - 1);
};
print $fact->(5), "\n"; # 120
Edge cases#
A named
subdefinition is a statement, not an expression. It contributes nothing to its enclosing expression.my $x = sub foo {};parses as two statements;$xends upundef.The
sub NAME BLOCKforms are compile-time. The block body is parsed and compiled when the enclosing file orevalis compiled. Side effects inside the block run only when the sub is called, not when it is defined. By contrast,sub BLOCK(anonymous) evaluates at runtime every time the expression is reached, producing a new closure each time.Nested named subs close over nothing useful. A
subdefined inside anothersubis still installed in the package at compile time and does not capture lexicals from the enclosing call. Each call to the outer sub sees the same inner sub, warped around the first call’s lexicals. Use an anonymous sub for closures.Trailing
returnis optional but explicit is clearer. Withoutreturn, the value of the last expression is returned. If the last statement is a loop or a block, the return value is unspecified — do not rely on it.Assigning to
@_wholesale breaks aliasing.@_ = @_or@_ = (1, 2)replaces the array and later$_[0] = Xno longer reaches the caller.Passing a literal then modifying
$_[0]is fatal.upcase_in("x")dies withModification of a read-only value attemptedbecause$_[0]is aliased to the literal.Redefining a sub emits
Subroutine X redefinedunderuse warnings. Wrapping a redefinition requiresno warnings 'redefine'for the scope:no warnings 'redefine'; *Foo::bar = sub { ... };
subinside aBEGINblock is defined at compile time of the surrounding unit, same as anysubdeclaration; theBEGINwrapping does not change the timing of the declaration itself.A prototype after a space gotcha.
sub foo ($$)withuse feature 'signatures'is parsed as a signature, not a prototype. To attach a prototype under signatures, usesub foo :prototype($$) ($x, $y) { ... }.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
return— explicit return from a sub; without it the last expression’s value is returnedwantarray— inspect the calling context (list / scalar / void) from inside the bodycaller— information about who called this sub and from whereprototype— read back the prototype of a named or anonymous sub__SUB__— reference to the current sub without naming it; the tool for anonymous recursionmy— the usual way to unpack@_into named lexicals when not using signaturesmethod— class-syntax method declaration;use feature 'class'equivalent ofsubfor methods