Slides from my talk at London Perl Mongers on 2018-03-22 covering Perl6 Signatures in detail.
Special bonus slides for Type Checking and Multi methods.
2. No Signature
sub foo {
@_.say;
}
● Should be familiar to Perl devs
● All arguments put into lexical @_ array
● @_ array only populated with arguments in this case
3. No Signature (Note)
sub foo {
@_.say;
}
foo( A => 1 );
*ERRORS*
foo( ( A => 1 ) );
[A => 1]
When calling a sub (or method)
a Pair using either
A => 1 or :A(1) syntax will be
treated as a named argument.
4. Empty Signature
sub foo() {
say “I take orders from no one”;
}
● Specifically states this subroutine takes no arguments.
● Will error (generally at compile time) if called with arguments.
● Not just constants : eg. outer scope, state declarations
5. Empty Signature (methods)
method foo() {
say self.bar;
}
● Methods with an empty signature also error if called with
arguments.
● Have access to self (and the $ alias) though.
6. Positional Arguments
sub foo($a,$b,$c) {
say “$a : $b : $c”;
}
● Maps arguments to lexical variables based on position
● Errors unless the exact number of arguments are passed
7. Positional Arguments (methods)
method foo($foo: $a) {
say “{$foo.attr} : $a”;
}
● Optional initial argument separated with : defines another
reference for self that can be used in the method
● Useful with where clauses and multi methods
● Also can be used to specify class methods
8. Positional Arguments : Defaults and optional
sub foo($a,$b?,$c = 5) {
say “$a : $b : $c”;
}
foo(1,2)
1 : 2 : 5
● Any positions not filled will get their defaults
● Mark an argument as optional with ? after the name.
9. Positional Arguments : Sigils
sub foo(@a) {
say @a;
}
foo(1,2)
Errors
foo( [1,2] )
[1,2]
@ and % sigils are type signifiers for Positional
and Associative roles.
10. Positional Arguments : Flattening Slurpy
sub foo(*@a) {
say @a;
}
foo(1,2)
[1,2]
foo( 1,[2,3] )
[1,2,3]
Single * will slurp and flatten all remaining
positional arguments.
foo(1,(2,3))
[1,2,3]
foo(1,{2 => 3})
[1,{2=>3}]
11. Positional Arguments : Non Flattening Slurpy
sub foo(**@a) {
say @a;
}
foo(1,2)
[1,2]
foo( 1,[2,3] )
[1,[2,3]]
Double * will slurp all remaining positional
arguments but not flatten lists or hashes.
foo(1,(1,2))
[1,(1,2)]
foo(1,{2 => 3})
[1,{2=>3}]
12. Positional Arguments : Single Rule Slurpy
sub foo(+@a) {
say @a;
}
foo(1)
[1]
foo( [2,3] )
[2,3]
A + slurpy will flatten a single iterable object
into the arguments array. Otherwise it works
like **.
foo(1,[2,3])
[1,[2,3]]
foo(1,{2 => 3})
[1,{2=>3}]
13. Positional Arguments : Combinations
sub foo($a,*@b) {
say “$a :
{@b.perl}”;
}
foo(1)
1 : []
foo( 1,[2,3] )
1 : [2,3]
● You can combine positional and slurpy
argument.
● The slurpy has to come last.
● You can only have one slurpy argument.
foo(1,2,3)
1 : [2,3]
foo(1,2,3,{a => 5})
1:[2,3,:a(5)]
14. Named Arguments
sub foo(:$a,:$b!) {
say “$a & $b”;
}
foo(a=>”b”,b=>”c”)
b & c
foo(:a<bar>)
Required named parameter 'b'
not passed
● Define named arguments with a ‘:’ in front
of the lexical variable.
● Named arguments are not required.
● Append the name with ! to make it
required.
foo(:b<bar>)
& bar
Use of uninitialized value $a of
type Any in string context.
15. Alternate Named Arguments
sub foo(:bar(:$b)) {
say $b;
}
foo(b=>”a”)
a
foo(:bar<bar>)
bar
● Alternate argument names can be
nested multiple times :
○ :$val
○ :v($val)
■ :v() in call
○ :v(:$val)
■ :v() or :val()
○ :valid(:v(:$val))
● All referenced as $val in the sub
● Useful for sub MAIN
16. Combining Named and Positional Arguments
sub foo($a,:$b) {
say $a if $b;
}
foo(“Hi”,:b)
Hi
foo(“Crickets”)
● Positional arguments have to be
defined before named.
● You can combine a slurpy
positional and named arguments.
17. Named Arguments : Slurpy Hash
sub foo(*%a) {
say %a;
}
foo(a=>b)
{a => b}
Using * on a hash will take all the named
argument pairs and put them in the given hash.
foo( b => [5,6],
:a(b) )
{b => [5,6], a => b}
foo( :a, :!b )
{ a => True,
b => False }
18. Bonus Slide : Types
sub num-in-country(:$num, :$ccode){...}
sub num-in-country(UInt :$num, Str :$ccode){...}
sub num-in-country(UInt :$num, Str :$ccode
where * ~~ /^ <[a..z]> ** 2 $/ ){...}
subset CCode of Str where * ~~ /^ <[a..z]> ** 2 $/;
sub num-in-country(UInt :$num, CCode :$ccode){...}
Sub coerced-type( Str() $a ) { say “$a could have been many...” }
19. Bonus Slide : Multi Call
subset Seven of Int where * == 7;
multi sub foo() { 'No args' }
multi sub foo(5) { 'Called with 5' }
multi sub foo(Seven $) { 'Called with 7' }
multi sub foo( *@a ) { '*@a' }
multi sub foo( $a ) { '$a' }
multi sub foo( Cool $b ) { 'Cool $b' }
multi sub foo( Int $b ) { 'Int $b' }
multi sub foo( Int $b where * > 0 ) { 'Int $b where * > 0' }