Perl6::Overview::Subroutine - Subroutines
sub foo ($bar, @baz, %grtz) {...} # Global (our()) subroutine &foo, taking a scalar, an array, # and a hash. foo(42, @array, %hash); # works foo(bar => 42, baz => @array, grtz => %hash); # works as well foo(:bar(42), :baz(@array), :grtz(%hash)); # ditto # Mixing named and positional arguments is allowed, too: foo(42, :baz(@array), :grtz(%hash)); # works Positional parameters are required by default.
sub foo (:$named_only) {...} foo 42; # illegal foo named_only => 42; # ok foo :named_only(42); # ok
Named parameters are optional be default.
sub foo ($bar?) {...} sub foo ($bar is optional) {...} foo(); # ok foo(42); # ok sub foo (:$bar?) {...} # allowed, but could be written as sub foo (:$bar) {...} # as named parameters are optional by # default.
You can specify defaults:
sub foo ($bar = 42) {...} foo(); # $bar is 42 foo(17); # $bar is 17 sub foo (:$bar = 42) {...} foo(); # $bar is 42 foo(:bar(17)); # $bar is 17
Defaults are calculated at runtime and can even refer to preceding parameters:
sub foo ($bar, $baz = grmbl($bar)) {...}
sub foo (:$bar!) {...} # Required named parameter $bar sub foo (:$bar is required) {...} # same sub foo ($bar!) {...} # allowed, but could be written as sub foo ($bar) {...} # as positional parameters are required # by default.
Slurpy arrays slurp all remaining positional arguments:
sub foo ($a, $b, *@rest) {...} foo 1,2,3,4,5; # $a is 1, $b is 2, @rest is (3,4,5) foo 1,2; # $a is 1, $b is 2, @rest is ()
Slurpy hashes slurp all remaining named arguments:
sub foo ($a, $b, *%rest) {...} foo 1,2,3,4,5; # error: "Too many positional arguments" foo 1,2, :foo<bar>; # $a is 1, $b is 2, %rest is (foo => "bar")
By default, all parameters are read-only aliases:
sub foo ($var) { $var = 42 }; my $bar = 17; foo($bar); # dies: "Cannot modify read-only variable" "is rw" causes *no* read-only proxy to be created: sub foo ($var is rw) { $var = 42 }; my $bar = 17; foo($bar); # works, $bar is 42 after the function call
"is copy" copies the variable, the original will remain unaffected:
sub foo ($var is copy) { $var = 42 }; my $bar = 17; foo($bar); # works, but $bar unchanged
(This is the same as Perl 5's "my $var = shift" idiom.)
Note that "is rw" and "is copy" only refer to the first level of a structure:
sub foo (@array) { @array[42] = 17 } foo @some_array; # works, even though @array is not "is rw"; # @some_array[42] changed to 17 sub foo (@array) { push @array, 17 } foo @some_array; # does not work ("Cannot modify read-only # variable") sub foo (@array is rw) { push @array, 17 } foo @some_array; # does work, 17 appended to @some_array
Similarly, "is rw" and "is copy" may not do what you think they do on references:
sub foo (Ref $ref) { $$ref = 17 } foo $some_ref; # works, $$some_ref changed to 17 sub foo (Ref $ref) { $ref = \$other_var } foo $some_ref; # dies ("Cannot modify read-only variable" sub foo (Ref $ref is rw) { $ref = \$other_var } foo $some_ref; # works, $some_ref changed to \$other_var
The following code is legal and does not die:
sub foo ($var) { $var := $some_other_var; ... } foo 42; foo $some_var;
But the original containers are not modified in any way, neither 42 nor $some_var get rebound, only &foo's $var does no longer refer to 42 or $some_var, but to $some_other_var.
[XXX: Unpacking arrays and hashes, pattern matching, specifying parameter types]
sub foo {...} # our() subroutine, may be called before the declaration: foo(...); sub foo {...} # legal # (Note that this is sugar for # BEGIN { our &foo := sub (...) {...} }) my sub foo {...} # Lexical (my()) subroutine, may not be called before the declaration. # Only visible in the scope in which it was declared: { my sub foo {...}; foo(...) } # legal { foo() } # illegal # ("Can't find subroutine &foo") our sub foo {...} # our() subroutine, may not be called before the declaration. sub *foo {...} # Really global subroutine, visible in all scopes.
"is rw" applied to a subroutine causes *no* read-only proxy to be created around the return value of a subroutine: sub foo { $some_var } foo() = 42; # error: "Cannot modify read-only variable" sub foo is rw { $some_var } foo() = 42; # works, $some_var set to 42 sub foo is rw { 17 } foo() = 42; # still does not work -- 17 is a constant # Instead use: sub foo is rw { my $var = 17 } foo() = 42; # works
Following the "assignments should look like assignments" rule, usage of "is rw" for accessor-like subroutines is encouraged. You can use the "Proxy" class to validate input:
sub foo () is rw { return new Proxy: FETCH => { ...code to return on get... }, STORE => -> $new { ...code to run on assignment... }; } say foo(); foo() = 42;
Note that assigning a proxy to a variable with = will loose the proxy's magicalness:
my $var = foo(); # invokes FETCH on foo() $var = $invalid_input; # works; STORE not called
You have to use binding (:=) instead:
my $var := foo(); $var = $invalid_input; # STORE called
Whitespace matters:
foo 42; # calls &foo, one positional argument (number 42) foo(42); # same, the parens are sub call parens (postfix .()) foo (42); # same, but the parens are grouping parens foo 42, 23; # two positional arguments (42 and 23) foo(42, 23); # same foo (42, 23); # one positional argument (the array (42, 23))
Parentheses matter:
foo bar => 42; # one named argument (42) foo :bar(42); # same foo(bar => 42); # same, the parens are grouping parens foo(:bar(42)); # same, the parens are grouping parens foo (bar => 42); # one positional argument (the pair (bar => 42)) foo (:bar(42)); # same, the parens mark the pair to be a Pair object, # not a named argument
Splatting:
foo $pair; # one positional argument ($pair) foo [,] $pair; # one named argument # ($pair.value passed by the name $pair.key) foo @array; # one positional argument (the array @array) foo [,] @array; # many positional arguments # (@array's contents are passed positionally) foo %hash; # one positional argument (the hash %hash) foo [,] %hash; # many named arguments # (%hash.values are passed by the names %hash.keys)
To install Perl6::Doc, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Perl6::Doc
CPAN shell
perl -MCPAN -e shell install Perl6::Doc
For more information on module installation, please visit the detailed CPAN module installation guide.