sub foo ( $self, # parameter declarations starting with '?' examine, # but don't consume any further arguments: ?*@args, # @args is set to the equivalent of @_ with one # arg shifted; i.e. like a slurpy but peeking ahead # and not actually consuming any args; the '*' means # that each @args element is aliased to a passed arg ?$peek_a, # $peek_a is bound to next arg but without consuming it ??$has_a, # $has_a is set to true if there's an argument for $a $a, # normal scalar parameter ?{ print $a },# embedded code block - runs code; doesn't shift args Dog $spot, # works the same as 'my Dog $spot' $b :shared, # you can use normal variable attributes $c :ro, # at compile time, $c in lvalue context croaks \@ary, # aliases @ary to a passed array reference \%hash, # aliases %hash to a passed hash reference *$scalar, # aliases $scalar to the next argument # Constraints and coercions: $d!, # croak if $d not defined $e isa Foo::Bar, # croak if $e isn't of that class $f is Int where $_ > 0, # croak if $f not a positive integer $x = 0, # a default value $y?, # short for $y = undef \@array?, # short for \@array = [] :$name1 = 0, :$name2 = 0, # consume name-value pairs (name1 => ..., name2 => ....) @rest # slurp up any remaining arguments ) { .... } #### sub f ($x :foo, $y :bar(baz) bar2(baz2), ...) { ... } #### my $x :foo; my $y :bar(baz) bar2(baz2); #### my ($x, $y) :foo(foo_arg) :bar(bar_arg); #### use attributes (); my ($x,$y); attributes->import(, __PACKAGE__, \$x, "foo(foo_arg)", "bar(bar_arg)"); attributes->import(, __PACKAGE__, \$y, "foo(foo_arg)", "bar(bar_arg)"); #### sub foo ( $pos1, # positional parameter; consumes 1 arg $pos2, # positional parameter; consumes 1 arg :$name1, # named parameter, consumes ("name1", value) arg pair :$name2, # named parameter, consumes ("name2", value) arg pair @rest, # consumes all unrecognised name/value pairs ) { ... } #### ?$x peek ahead to the next arg ??$x peek ahead and see if there is a next arg ?@a peek ahead and copy all remaining args ?%h peek ahead and copy all remaining key/val arg pairs ?{ code } execute some code without consuming any args #### sub foo { # the lexical vars $a, @b and %c are aliased to the things pointed # to by the reference values passed as the first three arguments: \$a \@b, \%c, # $d is aliased to the fourth arg: *$d, # $e is aliased to the fifth arg, but at compile time, any use # of $e in lvalue context within this lexical scope is a compile # time error: *$e :ro, # the elements of @f are aliased to any remaining args, # i.e. a slurpy with aliasing ...: *@f # .. or a slurpy hash; every second remaining arg is aliased to # the hash's values: *%g ) { ... } #### sub f( $self isa Foo::Bar, # croak unless $self->isa('Foo::Bar'); $foo isa Foo::Bar?, # croak unless undef or of that class $a!, # croak unless $a is defined $b is Int, # croak if $b not int-like $c is Int?, # croak unless undefined or int-like $d is PositiveInt, # user-defined type $e is Int where $_ >= 1, # multiple constraints $f is \@, # croak unless array ref $aref as ref ? $_ : [ $_ ] # coercions: maybe modify the param ) { ...}; #### sub f (Int $x) { ... } #### sub f ($x) { croak unless defined $x && !ref($x) && $x =~ /\A-?[0-9]+\Z/; ....; } #### sub f (Some::Arbitrary::Class $x) { ... } #### sub f ($x) { croak unless defined $x && ref($x) && $x->isa(Some::Arbitrary::Class); ...; } #### sub f ($x where * < 10*$y) { ... } #### sub f($a, $b, $c, ... ) { BODY; } #### sub f { my $a = ....; my $b = ....; my $c = ....; ....; BODY; }