| 1 | =head1 NAME |
|---|
| 2 | |
|---|
| 3 | Perl6::Overview::Subroutine - Subroutines |
|---|
| 4 | |
|---|
| 5 | =head1 DESCRIPTION |
|---|
| 6 | |
|---|
| 7 | =head2 Positional parameters |
|---|
| 8 | |
|---|
| 9 | sub foo ($bar, @baz, %grtz) {...} |
|---|
| 10 | # Global (our()) subroutine &foo, taking a scalar, an array, |
|---|
| 11 | # and a hash. |
|---|
| 12 | foo(42, @array, %hash); # works |
|---|
| 13 | foo(bar => 42, baz => @array, grtz => %hash); # works as well |
|---|
| 14 | foo(:bar(42), :baz(@array), :grtz(%hash)); # ditto |
|---|
| 15 | # Mixing named and positional arguments is allowed, too: |
|---|
| 16 | foo(42, :baz(@array), :grtz(%hash)); # works |
|---|
| 17 | |
|---|
| 18 | Positional parameters are required by default. |
|---|
| 19 | |
|---|
| 20 | =head2 Named parameters |
|---|
| 21 | |
|---|
| 22 | sub foo (:$named_only) {...} |
|---|
| 23 | foo 42; # illegal |
|---|
| 24 | foo named_only => 42; # ok |
|---|
| 25 | foo :named_only(42); # ok |
|---|
| 26 | |
|---|
| 27 | Named parameters are optional be default. |
|---|
| 28 | |
|---|
| 29 | =head2 Optional parameters |
|---|
| 30 | |
|---|
| 31 | sub foo ($bar?) {...} |
|---|
| 32 | sub foo ($bar is optional) {...} |
|---|
| 33 | foo(); # ok |
|---|
| 34 | foo(42); # ok |
|---|
| 35 | |
|---|
| 36 | sub foo (:$bar?) {...} # allowed, but could be written as |
|---|
| 37 | sub foo (:$bar) {...} # as named parameters are optional by |
|---|
| 38 | # default. |
|---|
| 39 | |
|---|
| 40 | You can specify defaults: |
|---|
| 41 | |
|---|
| 42 | sub foo ($bar = 42) {...} |
|---|
| 43 | foo(); # $bar is 42 |
|---|
| 44 | foo(17); # $bar is 17 |
|---|
| 45 | |
|---|
| 46 | sub foo (:$bar = 42) {...} |
|---|
| 47 | foo(); # $bar is 42 |
|---|
| 48 | foo(:bar(17)); # $bar is 17 |
|---|
| 49 | |
|---|
| 50 | Defaults are calculated at runtime and can even refer to preceding parameters: |
|---|
| 51 | |
|---|
| 52 | sub foo ($bar, $baz = grmbl($bar)) {...} |
|---|
| 53 | |
|---|
| 54 | =head2 Required parameters |
|---|
| 55 | |
|---|
| 56 | sub foo (:$bar!) {...} # Required named parameter $bar |
|---|
| 57 | sub foo (:$bar is required) {...} # same |
|---|
| 58 | |
|---|
| 59 | sub foo ($bar!) {...} # allowed, but could be written as |
|---|
| 60 | sub foo ($bar) {...} # as positional parameters are required |
|---|
| 61 | # by default. |
|---|
| 62 | |
|---|
| 63 | =head2 Slurpy parameters |
|---|
| 64 | |
|---|
| 65 | Slurpy arrays slurp all remaining positional arguments: |
|---|
| 66 | |
|---|
| 67 | sub foo ($a, $b, *@rest) {...} |
|---|
| 68 | foo 1,2,3,4,5; # $a is 1, $b is 2, @rest is (3,4,5) |
|---|
| 69 | foo 1,2; # $a is 1, $b is 2, @rest is () |
|---|
| 70 | |
|---|
| 71 | Slurpy hashes slurp all remaining named arguments: |
|---|
| 72 | |
|---|
| 73 | sub foo ($a, $b, *%rest) {...} |
|---|
| 74 | foo 1,2,3,4,5; # error: "Too many positional arguments" |
|---|
| 75 | foo 1,2, :foo<bar>; # $a is 1, $b is 2, %rest is (foo => "bar") |
|---|
| 76 | |
|---|
| 77 | =head2 "is rw" |
|---|
| 78 | |
|---|
| 79 | By default, all parameters are read-only aliases: |
|---|
| 80 | |
|---|
| 81 | sub foo ($var) { $var = 42 }; |
|---|
| 82 | my $bar = 17; foo($bar); # dies: "Cannot modify read-only variable" |
|---|
| 83 | |
|---|
| 84 | "is rw" causes *no* read-only proxy to be created: |
|---|
| 85 | |
|---|
| 86 | sub foo ($var is rw) { $var = 42 }; |
|---|
| 87 | my $bar = 17; foo($bar); # works, $bar is 42 after the function call |
|---|
| 88 | |
|---|
| 89 | =head2 "is copy" |
|---|
| 90 | |
|---|
| 91 | "is copy" copies the variable, the original will remain unaffected: |
|---|
| 92 | |
|---|
| 93 | sub foo ($var is copy) { $var = 42 }; |
|---|
| 94 | my $bar = 17; foo($bar); # works, but $bar unchanged |
|---|
| 95 | |
|---|
| 96 | (This is the same as Perl 5's "my $var = shift" idiom.) |
|---|
| 97 | |
|---|
| 98 | Note that "is rw" and "is copy" only refer to the first level of a |
|---|
| 99 | structure: |
|---|
| 100 | |
|---|
| 101 | sub foo (@array) { @array[42] = 17 } |
|---|
| 102 | foo @some_array; # works, even though @array is not "is rw"; |
|---|
| 103 | # @some_array[42] changed to 17 |
|---|
| 104 | |
|---|
| 105 | sub foo (@array) { push @array, 17 } |
|---|
| 106 | foo @some_array; # does not work ("Cannot modify read-only |
|---|
| 107 | # variable") |
|---|
| 108 | |
|---|
| 109 | sub foo (@array is rw) { push @array, 17 } |
|---|
| 110 | foo @some_array; # does work, 17 appended to @some_array |
|---|
| 111 | |
|---|
| 112 | Similarly, "is rw" and "is copy" may not do what you think they do |
|---|
| 113 | on references: |
|---|
| 114 | |
|---|
| 115 | sub foo (Ref $ref) { $$ref = 17 } |
|---|
| 116 | foo $some_ref; # works, $$some_ref changed to 17 |
|---|
| 117 | |
|---|
| 118 | sub foo (Ref $ref) { $ref = \$other_var } |
|---|
| 119 | foo $some_ref; # dies ("Cannot modify read-only variable" |
|---|
| 120 | |
|---|
| 121 | sub foo (Ref $ref is rw) { $ref = \$other_var } |
|---|
| 122 | foo $some_ref; # works, $some_ref changed to \$other_var |
|---|
| 123 | |
|---|
| 124 | =head2 Re-binding parameters |
|---|
| 125 | |
|---|
| 126 | The following code is legal and does not die: |
|---|
| 127 | |
|---|
| 128 | sub foo ($var) { $var := $some_other_var; ... } |
|---|
| 129 | foo 42; |
|---|
| 130 | foo $some_var; |
|---|
| 131 | |
|---|
| 132 | But the original containers are not modified in any way, neither 42 |
|---|
| 133 | nor $some_var get rebound, only &foo's $var does no longer refer to |
|---|
| 134 | 42 or $some_var, but to $some_other_var. |
|---|
| 135 | |
|---|
| 136 | [XXX: Unpacking arrays and hashes, pattern matching, specifying |
|---|
| 137 | parameter types] |
|---|
| 138 | |
|---|
| 139 | =head2 Specifying the scope of a declaration |
|---|
| 140 | |
|---|
| 141 | sub foo {...} |
|---|
| 142 | # our() subroutine, may be called before the declaration: |
|---|
| 143 | foo(...); sub foo {...} # legal |
|---|
| 144 | # (Note that this is sugar for |
|---|
| 145 | # BEGIN { our &foo := sub (...) {...} }) |
|---|
| 146 | |
|---|
| 147 | my sub foo {...} |
|---|
| 148 | # Lexical (my()) subroutine, may not be called before the declaration. |
|---|
| 149 | # Only visible in the scope in which it was declared: |
|---|
| 150 | { my sub foo {...}; foo(...) } # legal |
|---|
| 151 | { foo() } # illegal |
|---|
| 152 | # ("Can't find subroutine &foo") |
|---|
| 153 | |
|---|
| 154 | our sub foo {...} |
|---|
| 155 | # our() subroutine, may not be called before the declaration. |
|---|
| 156 | |
|---|
| 157 | sub *foo {...} |
|---|
| 158 | # Really global subroutine, visible in all scopes. |
|---|
| 159 | |
|---|
| 160 | =head2 "is rw" on a subroutine |
|---|
| 161 | |
|---|
| 162 | "is rw" applied to a subroutine causes *no* read-only proxy to be |
|---|
| 163 | created around the return value of a subroutine: |
|---|
| 164 | |
|---|
| 165 | sub foo { $some_var } |
|---|
| 166 | foo() = 42; # error: "Cannot modify read-only variable" |
|---|
| 167 | |
|---|
| 168 | sub foo is rw { $some_var } |
|---|
| 169 | foo() = 42; # works, $some_var set to 42 |
|---|
| 170 | |
|---|
| 171 | sub foo is rw { 17 } |
|---|
| 172 | foo() = 42; # still does not work -- 17 is a constant |
|---|
| 173 | # Instead use: |
|---|
| 174 | sub foo is rw { my $var = 17 } |
|---|
| 175 | foo() = 42; # works |
|---|
| 176 | |
|---|
| 177 | =head2 The "Proxy" class |
|---|
| 178 | |
|---|
| 179 | Following the "assignments should look like assignments" rule, usage of |
|---|
| 180 | "is rw" for accessor-like subroutines is encouraged. You can use the |
|---|
| 181 | "Proxy" class to validate input: |
|---|
| 182 | |
|---|
| 183 | sub foo () is rw { |
|---|
| 184 | return new Proxy: |
|---|
| 185 | FETCH => { ...code to return on get... }, |
|---|
| 186 | STORE => -> $new { ...code to run on assignment... }; |
|---|
| 187 | } |
|---|
| 188 | say foo(); |
|---|
| 189 | foo() = 42; |
|---|
| 190 | |
|---|
| 191 | Note that assigning a proxy to a variable with = will loose the proxy's |
|---|
| 192 | magicalness: |
|---|
| 193 | |
|---|
| 194 | my $var = foo(); # invokes FETCH on foo() |
|---|
| 195 | $var = $invalid_input; # works; STORE not called |
|---|
| 196 | |
|---|
| 197 | You have to use binding (:=) instead: |
|---|
| 198 | |
|---|
| 199 | my $var := foo(); |
|---|
| 200 | $var = $invalid_input; # STORE called |
|---|
| 201 | |
|---|
| 202 | =head2 Calling subroutines |
|---|
| 203 | |
|---|
| 204 | Whitespace matters: |
|---|
| 205 | |
|---|
| 206 | foo 42; # calls &foo, one positional argument (number 42) |
|---|
| 207 | foo(42); # same, the parens are sub call parens (postfix .()) |
|---|
| 208 | foo (42); # same, but the parens are grouping parens |
|---|
| 209 | |
|---|
| 210 | foo 42, 23; # two positional arguments (42 and 23) |
|---|
| 211 | foo(42, 23); # same |
|---|
| 212 | |
|---|
| 213 | foo (42, 23); # one positional argument (the array (42, 23)) |
|---|
| 214 | |
|---|
| 215 | Parentheses matter: |
|---|
| 216 | |
|---|
| 217 | foo bar => 42; # one named argument (42) |
|---|
| 218 | foo :bar(42); # same |
|---|
| 219 | foo(bar => 42); # same, the parens are grouping parens |
|---|
| 220 | foo(:bar(42)); # same, the parens are grouping parens |
|---|
| 221 | |
|---|
| 222 | foo (bar => 42); # one positional argument (the pair (bar => 42)) |
|---|
| 223 | foo (:bar(42)); # same, the parens mark the pair to be a Pair object, |
|---|
| 224 | # not a named argument |
|---|
| 225 | |
|---|
| 226 | Splatting: |
|---|
| 227 | |
|---|
| 228 | foo $pair; # one positional argument ($pair) |
|---|
| 229 | foo [,] $pair; # one named argument |
|---|
| 230 | # ($pair.value passed by the name $pair.key) |
|---|
| 231 | |
|---|
| 232 | foo @array; # one positional argument (the array @array) |
|---|
| 233 | foo [,] @array; # many positional arguments |
|---|
| 234 | # (@array's contents are passed positionally) |
|---|
| 235 | |
|---|
| 236 | foo %hash; # one positional argument (the hash %hash) |
|---|
| 237 | foo [,] %hash; # many named arguments |
|---|
| 238 | # (%hash.values are passed by the names %hash.keys) |
|---|