$30 off During Our Annual Pro Sale. View Details »

Perl 5 MOP

Perl 5 MOP

This is a talk given at YAPC::EU 2012 in Frankfurt Germany on the proposed Meta Object Protocol for Perl 5

Stevan Little

August 22, 2012
Tweet

More Decks by Stevan Little

Other Decks in Programming

Transcript

  1. Perl 5
    MOP
    Stevan Little ● YAPC::EU 2012 ● Frankfurt, Germany
    Wednesday ● 22 August 2012
    So I have been kicking around some Larry quotes in talks recently. And I decided I wanted to show 3 of my
    favorites here. But before I did this I asked Larry about each one (mostly to be sure he really said them).

    View Slide

  2. Perl was always designed to be an evolving
    language.
    – Larry Wall
    So I asked Larry about this one he told me basically that “adding sigils to variables allowed for builtins to be added and not
    conflict with variables” , just think about that for a moment. Cool right?

    View Slide

  3. Perl 5 was my rewrite of Perl. I want Perl 6 to be
    the community's rewrite of Perl and of the
    community.
    – Larry Wall
    When I parse this sentence, I only find one community

    View Slide

  4. The whole intent of Perl 5's module system was
    to encourage the growth of Perl culture rather
    than the Perl core.
    – Larry Wall
    * Historical tidbit: Perl 4 had oraperl, etc, which split the community, Larry saw this and didnt want this to happen, so saw that
    modules were critical way to allowed the community to be lexically scoped
    * I think this conference and the others like it, YAPCs and Workshops and Mongers groups are an example of the
    success of this plan.

    View Slide

  5. last summer Jesse Vincent gave this talk at ... YAPC::NA, then again at YAPC::EU, then at OSCON, and then at
    YAPC::Asia, Jesse gave this talk and said a lot of interesting things.

    View Slide

  6. “Perl 5.16 and Beyond”
    by Jesse Vincent
    last summer Jesse Vincent gave this talk at ... YAPC::NA, then again at YAPC::EU, then at OSCON, and then at
    YAPC::Asia, Jesse gave this talk and said a lot of interesting things.

    View Slide

  7. “Perl 5.16 and Beyond”
    by Jesse Vincent
    ‣@yapc::na
    last summer Jesse Vincent gave this talk at ... YAPC::NA, then again at YAPC::EU, then at OSCON, and then at
    YAPC::Asia, Jesse gave this talk and said a lot of interesting things.

    View Slide

  8. “Perl 5.16 and Beyond”
    by Jesse Vincent
    ‣@yapc::na
    ‣@yapc::eu
    last summer Jesse Vincent gave this talk at ... YAPC::NA, then again at YAPC::EU, then at OSCON, and then at
    YAPC::Asia, Jesse gave this talk and said a lot of interesting things.

    View Slide

  9. “Perl 5.16 and Beyond”
    by Jesse Vincent
    ‣@yapc::na
    ‣@yapc::eu
    ‣@oscon
    last summer Jesse Vincent gave this talk at ... YAPC::NA, then again at YAPC::EU, then at OSCON, and then at
    YAPC::Asia, Jesse gave this talk and said a lot of interesting things.

    View Slide

  10. “Perl 5.16 and Beyond”
    by Jesse Vincent
    ‣@yapc::na
    ‣@yapc::eu
    ‣@oscon
    ‣@yapc::asia
    last summer Jesse Vincent gave this talk at ... YAPC::NA, then again at YAPC::EU, then at OSCON, and then at
    YAPC::Asia, Jesse gave this talk and said a lot of interesting things.

    View Slide

  11. Reducing the
    Perl Core
    the thing that jumped out at me was ...

    View Slide

  12. Core ↝ Modules
    the idea put forth was to move things into modules, where they can be loaded as needed, but not burden the core
    perl-guts with them.
    I used this neat unicode wavy arrow because there is a certain amount of handwaving here. Largely because he
    also talks about preserving past version semantics and other not so simple things.

    View Slide

  13. a simpler
    language
    is a more
    evolvable
    language

    View Slide

  14. a simpler
    language
    is a more
    maintainable
    language

    View Slide

  15. a simpler
    language
    is a more
    hackable
    language
    Does this mean we loose some part of what Perl is? Hell No, thats what the CPAN is for!

    View Slide

  16. MOP
    Lets first talk about what is a MOP.
    Meta Object Protocol

    View Slide

  17. Classes,
    Methods,
    Attributes &
    Instances
    MOP is just an API for these things. Note the uppercase, it is important. Class is not the same thing as class.

    View Slide

  18. ... an abstraction of a
    system of abstractions
    that is used to build
    abstractions.
    So, when my mother asks me “what is all this Moose stuff you do”, this is what I tell her.

    View Slide

  19. ... an abstraction of a
    system of abstractions
    that is used to build
    abstractions.
    an abstraction
    (the MOP)

    View Slide

  20. ... an abstraction of a
    system of abstractions
    that is used to build
    abstractions.
    system of abstractions
    (classes, methods, etc.)

    View Slide

  21. ... an abstraction of a
    system of abstractions
    that is used to build
    abstractions.
    build abstractions
    (your classes)

    View Slide

  22. *{$pkg . '::foo'} = \&bar;
    this is the original MOP, little akward in places, but it works. I know this because i had to use this MOP to write
    Moose with!

    View Slide

  23. So this is actually a picture of the Class::MOP meta-layer.

    View Slide

  24. So this is actually a picture of the p5-mop meta-layer. We are side stepping Module and Package for the moment
    so that we can focus on the class layer. However we might just keep it this way since tools like Package::Stash
    exist

    View Slide

  25. CODE
    Now lets look at some code

    View Slide

  26. class Point {
    has $x = 0;
    has $y = 0;
    method clear {
    ($x, $y) = (0, 0);
    }
    }

    View Slide

  27. class Point {
    has $x = 0;
    has $y = 0;
    method clear {
    ($x, $y) = (0, 0);
    }
    }
    class keyword
    - if no superclass, inherits from Object by default

    View Slide

  28. class Point {
    has $x = 0;
    has $y = 0;
    method clear {
    ($x, $y) = (0, 0);
    }
    }
    has keyword
    - "instance-lexical" scoping of attributes

    View Slide

  29. class Point {
    has $x = 0;
    has $y = 0;
    method clear {
    ($x, $y) = (0, 0);
    }
    }
    method keyword
    - the attributes are available in methods as lexical variables
    - the scope of them being carried around in the instance
    - the destructuring bind in the clear method

    View Slide

  30. my $point = Point->new(
    x => 10,
    y => 20
    );
    instance creation is pretty straight forward

    View Slide

  31. my $point = Point->new(
    x => 10,
    y => 20
    );
    we didn't have to write a &new method, because we inherited from Object

    View Slide

  32. my $point = Point->new(
    x => 10,
    y => 20
    );
    - constructor takes name/value pairs of the attributes (reasonably good default that can be changed via the MOP)

    View Slide

  33. class Point3D (extends => Point) {
    has $z = 0;
    method clear {
    super;
    $z = 0;
    }
    }
    extend a class

    View Slide

  34. class Point3D (extends => Point) {
    has $z = 0;
    method clear {
    super;
    $z = 0;
    }
    }
    the extends syntax

    View Slide

  35. class Point3D (extends => Point) {
    has $z = 0;
    method clear {
    super;
    $z = 0;
    }
    }
    the super syntax calling the superclass-method

    View Slide

  36. class BankAccount {
    has $balance ( is => 'ro' ) = 0;
    method deposit ($amount) {
    $balance += $amount
    }
    method withdraw ($amount) {
    die "Account overdrawn"
    if ($balance <= $amount);
    $balance -= $amount;
    }
    }

    View Slide

  37. class BankAccount {
    has $balance ( is => 'ro' ) = 0;
    method deposit ($amount) {
    $balance += $amount
    }
    method withdraw ($amount) {
    die "Account overdrawn"
    if ($balance <= $amount);
    $balance -= $amount;
    }
    }
    build in support for ro, rw and wo accessors (TODO)
    - this is actually a metadata expression
    - which is like annotations (Java), attributes (C//), decorators (Python)
    - it is executed at compile time and passed to the meta object being created
    - setting the default values of attributes

    View Slide

  38. class BankAccount {
    has $balance ( is => 'ro' ) = 0;
    method deposit ($amount) {
    $balance += $amount
    }
    method withdraw ($amount) {
    die "Account overdrawn"
    if ($balance <= $amount);
    $balance -= $amount;
    }
    }
    Isn’t it nice how clean the += and -= makes things

    View Slide

  39. class BankAccount {
    has $balance ( is => 'ro' ) = 0;
    method deposit ($amount) {
    # $self->balance(
    # $self->balance + $amount
    # );
    $balance += $amount
    }
    method withdraw ($amount) {
    # my $balance = $self->balance;
    die "Account overdrawn"
    if ($balance <= $amount);
    # $self->balance( $balance + $amount );
    $balance -= $amount;
    }
    }
    And guess what, that is 4 less method calls
    - note there is no reference to $self in this entire class

    View Slide

  40. class BankAccount {
    has $balance ( is => 'ro' ) = 0;
    method deposit ($amount) {
    $balance += $amount
    }
    method withdraw ($amount) {
    die "Account overdrawn"
    if ($balance <= $amount);
    $balance -= $amount;
    }
    }
    simple signatures on methods

    View Slide

  41. class CheckingAccount (extends => BankAccount) {
    has $overdraft_account ( is => 'rw' );
    method withdraw ($amount) {
    my $overdraft_amount = $amount - $self->balance;
    if ( $overdraft_account && $overdraft_amount > 0 ) {
    $overdraft_account->withdraw(
    $overdraft_amount
    );
    $self->deposit( $overdraft_amount );
    }
    super( $amount );
    }
    }

    View Slide

  42. class CheckingAccount (extends => BankAccount) {
    has $overdraft_account ( is => 'rw' );
    method withdraw ($amount) {
    my $overdraft_amount = $amount - $self->balance;
    if ( $overdraft_account && $overdraft_amount > 0 ) {
    $overdraft_account->withdraw(
    $overdraft_amount
    );
    $self->deposit( $overdraft_amount );
    }
    super( $amount );
    }
    }
    - $balance is not accessible in the subclass methods
    - attributes are completely private

    View Slide

  43. class CheckingAccount (extends => BankAccount) {
    has $overdraft_account ( is => 'rw' );
    method withdraw ($amount) {
    my $overdraft_amount = $amount - $self->balance;
    if ( $overdraft_account && $overdraft_amount > 0 ) {
    $overdraft_account->withdraw(
    $overdraft_amount
    );
    $self->deposit( $overdraft_amount );
    }
    super( $amount );
    }
    }
    Make a note here about where we differ from Moose, in Moose the super call will actually pass @_ through for you
    and not allow you to change it. Here actually w do do that, this actually behaves much more like SUPER pseudo
    package , you have to pass variables down yourself

    View Slide

  44. role Equality {
    method equal_to;
    method not_equal_to ($other) {
    not $self->equal_to($other);
    }
    }
    we also have roles, horray!
    - apply this role to something you might wish to be able to test equality

    View Slide

  45. role Equality {
    method equal_to;
    method not_equal_to ($other) {
    not $self->equal_to($other);
    }
    }
    methods with no body are 'required' methods

    View Slide

  46. role Equality {
    method equal_to;
    method not_equal_to ($other) {
    not $self->equal_to($other);
    }
    }
    and we supply one method, which just negates the equal_to check that a consuming client will be required to
    implement

    View Slide

  47. role Comparable (with => Equality) {
    method compare;
    method equal_to ($other) {
    $self->compare($other) == 0
    }
    method greater_than ($other) {
    $self->compare($other) == 1
    }
    method less_than ($other) {
    $self->compare($other) == -1
    }
    }
    roles can consume other roles ...

    View Slide

  48. role Comparable (with => Equality) {
    method compare;
    method equal_to ($other) {
    $self->compare($other) == 0
    }
    method greater_than ($other) {
    $self->compare($other) == 1
    }
    method less_than ($other) {
    $self->compare($other) == -1
    }
    }

    View Slide

  49. role Comparable (with => Equality) {
    method compare;
    method equal_to ($other) {
    $self->compare($other) == 0
    }
    method greater_than ($other) {
    $self->compare($other) == 1
    }
    method less_than ($other) {
    $self->compare($other) == -1
    }
    }
    here, we add one more required method, and again implement the role in terms of that method

    View Slide

  50. role Printable {
    method as_string;
    }
    roles can be just interfaces too

    View Slide

  51. role Printable {
    method as_string;
    }

    View Slide

  52. class DE::Currency (with => [ Comparable, Printable ]) {
    has $amount ( is => 'rw' )= 0;
    method compare ($other) {
    $amount <=> $other->amount
    }
    method as_string {
    sprintf '€ %0.2f' => $amount
    }
    }
    classes can consume roles (more then one if they want)

    View Slide

  53. class DE::Currency (with => [ Comparable, Printable ]) {
    has $amount ( is => 'rw' )= 0;
    method compare ($other) {
    $amount <=> $other->amount
    }
    method as_string {
    sprintf '€ %0.2f' => $amount
    }
    }

    View Slide

  54. class DE::Currency (with => [ Comparable, Printable ]) {
    has $amount ( is => 'rw' )= 0;
    method compare ($other) {
    $amount <=> $other->amount
    }
    method as_string {
    sprintf '€ %0.2f' => $amount
    }
    }
    and we are implementing the compare from the Comparable role

    View Slide

  55. class DE::Currency (with => [ Comparable, Printable ]) {
    has $amount ( is => 'rw' )= 0;
    method compare ($other) {
    $amount <=> $other->amount
    }
    method as_string {
    sprintf '€ %0.2f' => $amount
    }
    }
    and we are implementing the Printable role

    View Slide

  56. class Foo {
    has $bar;
    method bar { $baz };
    }
    - spelling errors on slots are compile time errors
    - similar to inside-out objects, but less cumbersome

    View Slide

  57. class Foo {
    has $bar;
    method bar { $baz };
    }

    View Slide

  58. package Foo;
    use strict;
    use warnings;
    class Bar {
    has $baz;
    method foo { $baz }
    }
    packages can contain classes
    - because classes are first class citizens just like subs, etc.
    - this is much like other langauges (Java, etc)
    - classes don't need strict and warnings
    - it would be on by default

    View Slide

  59. my $foobar = Foo::Bar->new(
    baz => 'gorch'
    );
    ... and they are called just as you would expect

    View Slide

  60. package MyApp::Reports;
    use strict;
    use warnings;
    our $CONFIG = MyApp::Config->load;
    sub create_dbh { ... }
    class Finance {
    has $money_to_make = 10_000_000;
    method create_report {
    my $dbh = create_dbh;
    # ...
    $self->print_report( $CONFIG );
    }
    }

    View Slide

  61. package MyApp::Reports;
    use strict;
    use warnings;
    our $CONFIG = MyApp::Config->load;
    sub create_dbh { ... }
    class Finance {
    has $money_to_make = 10_000_000;
    method create_report {
    my $dbh = create_dbh;
    # ...
    $self->print_report( $CONFIG );
    }
    }
    - the class has access to the package scope as well

    View Slide

  62. package MyApp::Reports;
    use strict;
    use warnings;
    our $CONFIG = MyApp::Config->load;
    sub create_dbh { ... }
    class Finance {
    has $money_to_make = 10_000_000;
    method create_report {
    my $dbh = create_dbh;
    # ...
    $self->print_report( $CONFIG );
    }
    }
    - this means static class scoped data is simple

    View Slide

  63. package MyApp::Reports;
    use strict;
    use warnings;
    our $CONFIG = MyApp::Config->load;
    sub create_dbh { ... }
    class Finance {
    has $money_to_make = 10_000_000;
    method create_report {
    my $dbh = create_dbh;
    # ...
    $self->print_report( $CONFIG );
    }
    }
    - this means you can have subs that are not part of the class namespace

    View Slide

  64. package MyApp::Reports;
    use strict;
    use warnings;
    our $CONFIG = MyApp::Config->load;
    my sub create_dbh { ... }
    class Finance {
    has $money_to_make = 10_000_000;
    method create_report {
    my $dbh = create_dbh;
    # ...
    $self->print_report( $CONFIG );
    }
    }
    And, likely in 5.18 or 5.20, there will be private subs, so now you have private subs, they are not methods, but
    they are inaccessible from outside of the package and they are not part of the class’s dispatch space

    View Slide

  65. package DB::FlatFile;
    use Path::Class qw[ file ];
    class DataFile {
    has $path;
    has $file;
    has $data ( is => 'ro' );
    BUILD {
    $file = file( $path );
    $data = [ $file->slurp(chomp => 1) ];
    }
    }
    Here is an example of using this with exported functions

    View Slide

  66. package DB::FlatFile;
    use Path::Class qw[ file ];
    class DataFile {
    has $path;
    has $file;
    has $data ( is => 'ro' );
    BUILD {
    $file = file( $path );
    $data = [ $file->slurp(chomp => 1) ];
    }
    }
    - import functions into your package,
    - this removes the need to import anything into your class namespace.
    - no more namespace::clean hacks

    View Slide

  67. package DB::FlatFile;
    use Path::Class qw[ file ];
    class DataFile {
    has $path;
    has $file;
    has $data ( is => 'ro' );
    BUILD {
    $file = file( $path );
    $data = [ $file->slurp(chomp => 1) ];
    }
    }
    - this also shows BUILD
    - works mostly just like Moose does (the dispatch order anyway)
    - however both BUILD and DEMOLISH are not in the dispatch path (which is a good thing)

    View Slide

  68. use Fun;
    fun fibonacci ( $i ) {
    given ( $i ) {
    when ( $i == 0 ) { 0 }
    when ( $i == 1 ) { 1 }
    default {
    fibonacci( $i - 1 ) + fibonacci( $i - 2 )
    }
    }
    }
    Before I go into the next example, I want to show ... Fun

    View Slide

  69. use Fun;
    fun reduce ( $acc, $h, @tail ) {
    return $acc + $h unless @tail;
    return reduce( $acc + $h, @tail );
    }

    View Slide

  70. use Fun;
    fun convert_error ($err, $handle) {
    given ( $err ) {
    when ( qr/^No such file or directory/ ) {
    Err::NotFound->new( handle => $handle )->throw
    }
    when ( qr/^Permission denied/ ) {
    Err::PermissionsDenied->new( handle => $handle )->throw
    }
    default { warn $err if $err }
    }
    }
    class FileHandle {
    has $mode ( is => 'ro' );
    has $filename ( is => 'ro' );
    has $fh;
    BUILD ($params) {
    $fh = IO::File->new( $self->filename, $self->mode )
    or convert_error( $!, $self );
    }
    DEMOLISH {
    $fh->close or convert_error( $!, $self ) if $fh;
    }
    }
    Here is another example of working with older Perl modules, in this case capaturing and converting the errors
    from IO::File

    View Slide

  71. use Fun;
    fun convert_error ($err, $handle) {
    given ( $err ) {
    when ( qr/^No such file or directory/ ) {
    Err::NotFound->new( handle => $handle )->throw
    }
    when ( qr/^Permission denied/ ) {
    Err::PermissionsDenied->new( handle => $handle )->throw
    }
    default { warn $err if $err }
    }
    }
    class FileHandle {
    has $mode ( is => 'ro' );
    has $filename ( is => 'ro' );
    has $fh;
    BUILD ($params) {
    $fh = IO::File->new( $self->filename, $self->mode )
    or convert_error( $!, $self );
    }
    DEMOLISH {
    $fh->close or convert_error( $!, $self ) if $fh;
    }
    }
    Basically this is a utility function, private to the class (presumably this is in a package somewhere).

    View Slide

  72. use Fun;
    my fun convert_error ($err, $handle) {
    given ( $err ) {
    when ( qr/^No such file or directory/ ) {
    Err::NotFound->new( handle => $handle )->throw
    }
    when ( qr/^Permission denied/ ) {
    Err::PermissionsDenied->new( handle => $handle )->throw
    }
    default { warn $err if $err }
    }
    }
    class FileHandle {
    has $mode ( is => 'ro' );
    has $filename ( is => 'ro' );
    has $fh;
    BUILD ($params) {
    $fh = IO::File->new( $self->filename, $self->mode )
    or convert_error( $!, $self );
    }
    DEMOLISH {
    $fh->close or convert_error( $!, $self ) if $fh;
    }
    }
    And as soon as the my sub stuff is done, I am sure we can expect this

    View Slide

  73. use Fun;
    fun convert_error ($err, $handle) {
    given ( $err ) {
    when ( qr/^No such file or directory/ ) {
    Err::NotFound->new( handle => $handle )->throw
    }
    when ( qr/^Permission denied/ ) {
    Err::PermissionsDenied->new( handle => $handle )->throw
    }
    default { warn $err if $err }
    }
    }
    class FileHandle {
    has $mode ( is => 'ro' );
    has $filename ( is => 'ro' );
    has $fh;
    BUILD ($params) {
    $fh = IO::File->new( $self->filename, $self->mode )
    or convert_error( $!, $self );
    }
    DEMOLISH {
    $fh->close or convert_error( $!, $self ) if $fh;
    }
    }
    So what this function is doing then is converting string errors from IO::File to be exceptions (again note the smart
    match usage)

    View Slide

  74. use Devel::StackTrace;
    role Throwable {
    has $message ( is => 'ro' ) = 'Error';
    has $stack_trace ( is => 'ro' ) = Devel::StackTrace->new(
    frame_filter => sub { ... }
    );
    method throw { die $self }
    method format_message ( $message ) { "$message" }
    method as_string {
    $self->format_message( $message )
    . "\n"
    . $stack_trace->as_string
    }
    }
    Here is the actual role those two exceptions came from. Basically this is porting RJBS’s module Throwable (sorta, I
    simplified it a little for the slide)
    It nicely shows that it is also possible to use p5-mop and p5 classes together, the simplest is delgation, (though
    we do want to make inheritance work)

    View Slide

  75. use Devel::StackTrace;
    role Throwable {
    has $message ( is => 'ro' ) = 'Error';
    has $stack_trace ( is => 'ro' ) = Devel::StackTrace->new(
    frame_filter => sub { ... }
    );
    method throw { die $self }
    method format_message ( $message ) { "$message" }
    method as_string {
    $self->format_message( $message )
    . "\n"
    . $stack_trace->as_string
    }
    }
    here we are using the p5 OO module called Devel::StackTrace

    View Slide

  76. use Devel::StackTrace;
    role Throwable {
    has $message ( is => 'ro' ) = 'Error';
    has $stack_trace ( is => 'ro' ) = Devel::StackTrace->new(
    frame_filter => sub { ... }
    );
    method throw { die $self }
    method format_message ( $message ) { "$message" }
    method as_string {
    $self->format_message( $message )
    . "\n"
    . $stack_trace->as_string
    }
    }
    here is the throw method, which is not a class method, so you must do ->new->throw. However this is how it
    working in many popular languages

    View Slide

  77. use Devel::StackTrace;
    role Throwable {
    has $message ( is => 'ro' ) = 'Error';
    has $stack_trace ( is => 'ro' ) = Devel::StackTrace->new(
    frame_filter => sub { ... }
    );
    method throw { die $self }
    method format_message ( $message ) { "$message" }
    method as_string {
    $self->format_message( $message )
    . "\n"
    . $stack_trace->as_string
    }
    }
    we do not yet have overloading though, so for now you call the as_string method instead

    View Slide

  78. use Devel::StackTrace;
    role Throwable (with => [ Printable ]) {
    has $message ( is => 'ro' ) = 'Error';
    has $stack_trace ( is => 'ro' ) = Devel::StackTrace->new(
    frame_filter => sub { ... }
    );
    method throw { die $self }
    method format_message ( $message ) { "$message" }
    method as_string {
    $self->format_message( $message )
    . "\n"
    . $stack_trace->as_string
    }
    }
    And you know what, since we have as_string, we might as well make this Printable (our role from the Previous
    slide) so that people can do this ...

    View Slide

  79. use Try;
    try {
    # ...
    } catch {
    when ( Printable ) {
    warn $_->as_string;
    }
    default {
    warn $_;
    }
    }
    this basically means that code like this is doable ...

    View Slide

  80. use Try;
    try {
    # ...
    } catch {
    when ( Printable ) {
    warn $_->as_string;
    }
    default {
    warn $_;
    }
    }
    Note that this doesn’t say Try::Tiny, it says Try, this is because earlier this week Jesse Luehrs released it. It
    basically uses the Devel::CallParser module to implement a language level try/catch/finally statement.

    View Slide

  81. use Try;
    try {
    # ...
    } catch {
    when ( Printable ) {
    warn $_->as_string;
    }
    default {
    warn $_;
    }
    }
    this means you have a language level try/catch/finally construct. Currently this is backed by Try::Tiny, but Jesse
    and Florian are both working on fixing that (as well as making return to do the right thing inside a try).

    View Slide

  82. use Try;
    try {
    # ...
    } catch {
    when ( Printable ) {
    warn $_->as_string;
    }
    default {
    warn $_;
    }
    }
    this means you have a language level try/catch/finally construct. Currently this is backed by Try::Tiny, but Jesse
    and Florian are both working on fixing that (as well as making return to do the right thing inside a try).

    View Slide

  83. use Try;
    try {
    # ...
    } catch {
    when ( Printable ) {
    warn $_->as_string;
    }
    default {
    warn $_;
    }
    }
    My favorite part though is the use of when in the catch block. Note that this likely wouldn’t work straight away,
    you will need to do ...

    View Slide

  84. use Try;
    try {
    # ...
    } catch {
    when ( $_->does( Printable ) ) {
    warn $_->as_string;
    }
    default {
    warn $_;
    }
    }
    this, but if the recent smartmatch proposal from RJBS goes through, we should be able to do it

    View Slide

  85. http://github.com/stevan/p5-mop/
    Okay, and thats pretty much about it ...
    I want to remind everyone, almost all of these examples (other then the exceptions I mentioned) is actual runnable
    code. If you go to github you can check it out and try it (and please write tests)

    View Slide

  86. Moving to Moose Hackathon
    Oslo.pm
    Preikestolen, NO
    25 ↝ 30 August 2012
    ???

    View Slide

  87. #p6p5
    we will be talking here

    View Slide