Perl 6 Roles In Depth Jonathan Worthington YAPC::Europe 2009 Hi! - - PowerPoint PPT Presentation

perl 6 roles in depth
SMART_READER_LITE
LIVE PREVIEW

Perl 6 Roles In Depth Jonathan Worthington YAPC::Europe 2009 Hi! - - PowerPoint PPT Presentation

Perl 6 Roles In Depth Jonathan Worthington YAPC::Europe 2009 Hi! Hola! Hej hej! Ahoj! Salut! OH HAI Ol! Ciao! ! Perl 6 Roles In Depth .WHO? Perl 6 Roles In Depth Me Programming Perl since 2001ish Perl 6 Roles In


slide-1
SLIDE 1

Perl 6 Roles In Depth

Jonathan Worthington

YAPC::Europe 2009

slide-2
SLIDE 2

OH HAI

Hola! Salut! Ahoj! Привет! Hej hej! Hi! Ciao! Olá!

slide-3
SLIDE 3

.WHO?

Perl 6 Roles In Depth

slide-4
SLIDE 4

Me

Programming Perl since 2001ish

Perl 6 Roles In Depth

slide-5
SLIDE 5

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia

Perl 6 Roles In Depth

slide-6
SLIDE 6

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia Rakudo Perl 6 and Parrot hacker

Perl 6 Roles In Depth

slide-7
SLIDE 7

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia Rakudo Perl 6 and Parrot hacker Travel all over the place

Perl 6 Roles In Depth

slide-8
SLIDE 8

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia Rakudo Perl 6 and Parrot hacker Travel all over the place Usually hack to heavy metal

Perl 6 Roles In Depth

slide-9
SLIDE 9

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia Rakudo Perl 6 and Parrot hacker Travel all over the place Usually hack to heavy metal Good beer makes me happy

Perl 6 Roles In Depth

slide-10
SLIDE 10

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia Rakudo Perl 6 and Parrot hacker Travel all over the place Usually hack to heavy metal Good beer makes me happy Acrostics are awesome

Perl 6 Roles In Depth

slide-11
SLIDE 11

Me

Programming Perl since 2001ish Originally from UK, now live in Slovakia Rakudo Perl 6 and Parrot hacker Travel all over the place Usually hack to heavy metal Good beer makes me happy Acrostics are awesome LOL

Perl 6 Roles In Depth

slide-12
SLIDE 12

Roles

Perl 6 Roles In Depth

slide-13
SLIDE 13

Roles

Right at the heart of Perl 6

Perl 6 Roles In Depth

slide-14
SLIDE 14

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-15
SLIDE 15

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-16
SLIDE 16

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-17
SLIDE 17

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-18
SLIDE 18

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-19
SLIDE 19

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-20
SLIDE 20

Perl 6 Roles In Depth

So what is a role anyway?

A collection of zero or more… Methods Attributes Unlike a class, can not be instantiated

(if you try, a class is generated for you)

Classes in Perl 6 are mutable (with the

right pragma in force, can be monkey- typed), whereas roles are immutable

slide-21
SLIDE 21

Perl 6 Roles In Depth

What does a role look like?

Introduced with the role keyword Methods and attributes declared just as

they would be in a Perl 6 class

slide-22
SLIDE 22

Perl 6 Roles In Depth

What does a role look like?

Introduced with the role keyword Methods and attributes declared just as

they would be in a Perl 6 class

role DebugLog { ... }

slide-23
SLIDE 23

Perl 6 Roles In Depth

What does a role look like?

Introduced with the role keyword Methods and attributes declared just as

they would be in a Perl 6 class

role DebugLog { has @.log_lines; ... }

slide-24
SLIDE 24

Perl 6 Roles In Depth

What does a role look like?

Introduced with the role keyword Methods and attributes declared just as

they would be in a Perl 6 class

role DebugLog { has @.log_lines; has $.log_size is rw = 100; ... }

slide-25
SLIDE 25

Perl 6 Roles In Depth

What does a role look like?

Introduced with the role keyword Methods and attributes declared just as

they would be in a Perl 6 class

role DebugLog { has @.log_lines; has $.log_size is rw = 100; method log_message($message) { ... } }

slide-26
SLIDE 26

Perl 6 Roles In Depth

What does a role look like?

Introduced with the role keyword Methods and attributes declared just as

they would be in a Perl 6 class

role DebugLog { has @.log_lines; has $.log_size is rw = 100; method log_message($message) { @!log_lines.shift if @!log_lines.elems >= $!log_size; @!log_lines.push($message); } }

slide-27
SLIDE 27

Perl 6 Roles In Depth

Role Composition

A role is composed into a class using

the does trait

This adds the methods and attributes to

the class

End result is as if they had been written

inside the class in the first place

class WebCrawler does DebugLog { ... }

slide-28
SLIDE 28

Perl 6 Roles In Depth

Mix-ins

Allow the functionality of a role to be

added on a per-object basis (whereas compile time composition works on a per-class basis)

Does not affect any other instances of

the class

Methods from the role always override

any existing methods the object has

slide-29
SLIDE 29

Perl 6 Roles In Depth

Mix-ins Example

Suppose we want to trace what

happens to a certain object

Mix in the DebugLog role Later, we can output the lines that were

logged

$account does DebugLog; $account.log_lines>>.say;

slide-30
SLIDE 30

Perl 6 Roles In Depth

Mix-ins Example

Now we just need to add calls to the

log_message method

We can do this with the .? operator,

which calls the method if it exists

class Account { method change_password($new) { self.?log_message( "changing password to $new"); ... } }

slide-31
SLIDE 31

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-32
SLIDE 32

Perl 6 Roles In Depth

Sigil = Interface Contract

In Perl 6, a sigil implies an interface

contract

This interface contract is defined by a

role

You can only put things into a variable

with that sigil if it does the required role

Exception: variables with the $ sigil can

store anything (if not type-constrained)

slide-33
SLIDE 33

Perl 6 Roles In Depth

@ = Positional

The @ sigil implies the Positional role Promises that there will be a method

postcircumfix:<[ ]> that you can call

This is that gets called when you do an

index positionally into something

Note: optimizer (when we have one)

may emit something more lightweight

say @fact[1]; say @fact.postcircumfix:<[ ]>(1);

slide-34
SLIDE 34

Perl 6 Roles In Depth

% = Associative

The % sigil implies the Associative role Promises that there will be a method

postcircumfix:<{ }> that you can call

This is that gets called when you do an

index associatively into something

say %price<Cheese>; say %price.postcircumfix:<{ }>('Cheese');

slide-35
SLIDE 35

Perl 6 Roles In Depth

& = Callable

The & sigil implies the Callable role Promises that the thing can be invoked This role is done by things like Block,

Sub, Method and so forth

Will be able to do this role in your own

types (not yet supported in Rakudo)

Requires that the method

postcircumfix:<( )> is implemented

slide-36
SLIDE 36

Perl 6 Roles In Depth

Aside: Multiple Dispatch

Since a sigil implies the doing of a role,

you can use them in the signature of a multi-sub

multi what_is($it) { say "It's a scalar" } multi what_is(@it) { say "It's an array" } multi what_is(%it) { say "It's a hash" } multi what_is(&it) { say "It's code" } what_is([1,2,3]); # It's an array what_is({ x => 4, y => 2 });# It's a hash what_is(-> $x { 2 * $x }); # It's code what_is(42); # It's a scalar

slide-37
SLIDE 37

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-38
SLIDE 38

Perl 6 Roles In Depth

Parametric Roles

So far, we have seen roles as units of

functionality that we can compose into a class or mix in to an existing object

A role can also take parameters Allow for customization of the role's

behaviour on a per-use basis

In the problem space of C++ templates,

C#/Java Generics, System F, etc.

slide-39
SLIDE 39

Perl 6 Roles In Depth

Parametric Roles

Role parameters go in square brackets

after the role name

What goes between the square

brackets is a signature, just like with a sub/method.

role Can[::Contents] { method top_up(Contents $substance) { say "Yay...more {Contents.perl}!"; } }

slide-40
SLIDE 40

Perl 6 Roles In Depth

Parametric Roles

To do a parametric role, pass the

parameters in square brackets

It's much like doing a sub call Part of the type name; Can[Beer] is a

different type to Can[Coke].

class Beer { } class Coke { } my Can[Beer] $starobrno .= new; $starobrno.top_up(Beer.new); # Works $starobrno.top_up(Coke.new); # Exception

slide-41
SLIDE 41

Perl 6 Roles In Depth

Parametric Roles

If a role takes just one positional

parameter (like our current example), you can use the of keyword to specify the parameter

Can nest these too

my Can of Beer $starobrno .= new; my Pack of Can of Beer $six_pack .= new;

slide-42
SLIDE 42

Perl 6 Roles In Depth

Parametric Role Variants

Can define multiple variants of a role

that take different parameters

Selected using the same mechanisms

as multiple dispatch

role Can[::Contents] { # One parameter ... } role Can { # No parameters ... }

slide-43
SLIDE 43

Perl 6 Roles In Depth

Typed Arrays

Typed arrays restrict what may be

stored inside them

Implemented as a parametric role Can also write it as:

my Str @langs = <Perl Ruby PHP Python>; @langs = 1, 2, 3; # Error, Int @langs[2] = 'Smalltalk'; # Fine, Str push @langs, 4.2; # Error, Num my @langs of Str = <Perl Ruby PHP Python>;

slide-44
SLIDE 44

Perl 6 Roles In Depth

Typed Hashes

Typed hashes restrict what can be

stored as the values

Can build up nested typed data

structures

my Int %word_counts; %word_counts<monkey> = 5; # OK %word_counts<badger> = 0; # OK %word_counts<monkey> = "none"; # Error my @doc_word_counts of Hash of Int;

slide-45
SLIDE 45

Perl 6 Roles In Depth

A Common Fail

Note that the sigil already implies one

level of parametric type

What does this declare?

my Array @walruses;

slide-46
SLIDE 46

Perl 6 Roles In Depth

A Common Fail

Note that the sigil already implies one

level of parametric type

What does this declare? What does this signature accept?

my Array @walruses; sub herd(Array @cats) { ... }

slide-47
SLIDE 47

Perl 6 Roles In Depth

A Common Fail

Note that the sigil already implies one

level of parametric type

What does this declare? What does this signature accept? Answer for both: an Array of Arrays.

my Array @walruses; sub herd(Array @cats) { ... }

slide-48
SLIDE 48

Perl 6 Roles In Depth

A Common Fail

Note that the sigil already implies one

level of parametric type

What does this declare? What does this signature accept? Answer for both: an Array of Array. (Well, really a Positional of Array)

my Array @walruses; sub herd(Array @cats) { ... }

slide-49
SLIDE 49

Roles

Perl 6 Roles In Depth

Traits Typed data structures Sigils Composition and mix-ins

slide-50
SLIDE 50

Perl 6 Roles In Depth

So what are traits anyway?

A Perl 6 trait is something applied to a

declarand

A class that is currently being

declared

A routine that is currently being

declared

A variable that is currently being

declared

slide-51
SLIDE 51

Perl 6 Roles In Depth

Some Built-in Traits

A method or sub is marked as being

exported using a trait

Inheritance works through trait

application too

module Walrus { sub lose_bukit() is export { ... } } class PolarBear is Bear { ... }

slide-52
SLIDE 52

Perl 6 Roles In Depth

Trait Dispatch

Which trait to do is decided by a

multiple dispatch

If the trait name is a type name (e.g.

class or role), then the type is looked up and passed as the second positional argument

Otherwise, a pair of the given name is

passed

slide-53
SLIDE 53

Perl 6 Roles In Depth

Implementing A Trait Handler

Inside the trait implementation you can

do pretty much whatever you like

However, often a well-behaved trait will

mix in a role that provides an attribute

  • f the same name

Basic example: a doc trait

sub answer() is doc('Compute the answer') { return 42; } say &answer.doc;

slide-54
SLIDE 54

Perl 6 Roles In Depth

Implementing A Trait Handler

Declare a role to hold the

documentation string

Then implement a trait mod to apply it

to our routine

role doc { has $.doc is rw; } multi trait_mod:<is>(Routine $r, doc, $text) { $r does doc($text); }

slide-55
SLIDE 55

Perl 6 Roles In Depth

Traits On Variables

Can also apply a trait to a container Here's how we write the handler… …and how we use it.

multi trait_mod:<is>(Container $c, doc, $text) { $c does doc($text); } my %counts is doc('Count of each word'); say %counts.doc;

slide-56
SLIDE 56

Perl 6 Roles In Depth

Traits On Classes

Here be dragons: for classes, the jury is

still out on what you get as the declarand (the meta-class or some under-construction type object)

multi trait_mod:<is>(Class $c, doc, $text) { $c does doc($text); } class Bar is doc('Serves beer') { } say Bar.HOW.doc;

slide-57
SLIDE 57

Perl 6 Roles In Depth

Another Routine Trait Example

Goal: install a wrapper on a routine that

calls log_message on any parameter that does DebugLog

multi trait_mod:<is>(Routine $r is rw, :$logging!) { ... }

slide-58
SLIDE 58

Perl 6 Roles In Depth

Another Routine Trait Example

Goal: install a wrapper on a routine that

calls log_message on any parameter that does DebugLog

multi trait_mod:<is>(Routine $r is rw, :$logging!) { $r.wrap(sub (*@pos, *%named) { ... }); }

slide-59
SLIDE 59

Perl 6 Roles In Depth

Another Routine Trait Example

Goal: install a wrapper on a routine that

calls log_message on any parameter that does DebugLog

multi trait_mod:<is>(Routine $r is rw, :$logging!) { $r.wrap(sub (*@pos, *%named) { for @pos, %named.values -> $param { ... } ... }); }

slide-60
SLIDE 60

Perl 6 Roles In Depth

Another Routine Trait Example

Goal: install a wrapper on a routine that

calls log_message on any parameter that does DebugLog

multi trait_mod:<is>(Routine $r is rw, :$logging!) { $r.wrap(sub (*@pos, *%named) { for @pos, %named.values -> $param { if $param ~~ DebugLog { $param.log_message("Passed to " ~ $r.name); } } ... }); }

slide-61
SLIDE 61

Perl 6 Roles In Depth

Another Routine Trait Example

Goal: install a wrapper on a routine that

calls log_message on any parameter that does DebugLog

multi trait_mod:<is>(Routine $r is rw, :$logging!) { $r.wrap(sub (*@pos, *%named) { for @pos, %named.values -> $param { if $param ~~ DebugLog { $param.log_message("Passed to " ~ $r.name); } } nextsame; }); }

slide-62
SLIDE 62

Perl 6 Roles In Depth

That's All!

slide-63
SLIDE 63

Perl 6 Roles In Depth

Thank You!

slide-64
SLIDE 64

Perl 6 Roles In Depth

Questions?