SlideShare ist ein Scribd-Unternehmen logo
1 von 47
Downloaden Sie, um offline zu lesen
Moose
OOP for Perl.
What we expect from OOP

●    Classes (methods, types, attributes, open recursion...)

●    Encapsulation

●    Aggregation

●    Message passing and dynamic dispatch

●    Inheritance and polymorphism

●    Abstraction


    Skip definitions
Classes
●   Templates for defining objects state and
    behavior
Encapsulation

●   Specifying which classes may use the
    members of an object e.g:

    public, protected or private, determining
    whether they are available to all classes,
    sub-classes or only the defining class.
Aggregation

●   Object containing another object
Message passing and dynamic dispatch

●   Message passing is the process by which an object sends data to
    another object or asks the other object to invoke a method

●   when a method is invoked on an object, the object itself determines
    what code gets executed by looking up the method at run time in a
    table associated with the object (needed when multiple classes
    contain different implementations of the same method )
Inheritance and polymorphism
●   allows the programmer to treat derived class members just like
    their parent class's members ("Subclasses" are more specialized
    versions of a class, which inherit attributes and behaviors from
    their parent classes, and can introduce their own.)

●   a class has all the state and behavior of another class -
    polymorphism
What OOP features offers Perl?
●   MOP in Perl5:
    ●   Class - package

    ●   Object - blessed reference (a scalar type holding a reference to object
        data – object may be a hash, array, or reference to subroutine.)

    ●   Method - a subroutine within a package

    ●   Constructor – a method that returns reference to blessed variable
What OOP features offers Perl?

package Car;
    sub new {
        my $class = shift;
        my $brand = shift;
        my $self = {};
        $self->{'brand'} = $brand;
        bless ($self, $class);
        return $self;
        }
What OOP features offers Perl?
●   Encapsulation – in general only by convention.
●   Some tricks: private variable, private method, private function

     package Mom;                                  package Kido;

        sub new{                                   use base qw(Mom);
            my $class = shift;
            my $self = {                           sub ask_for_pin{
                'CARD_PIN' => '0000',                  my $self = shift;
                };                                     my $how = shift;
                                                       return &{$self}($how);
             my $closure = sub {                   }
                 my $arg = shift;
                 if ($arg and $arg eq 'nice'){
                     return $self->{'CARD_PIN'};   package main;
                     }                             my $mom = Mom->new();
                 else {                            my $kido = Kido->new();
                     return 'forget!';
                     }                             print $kido->ask_for_pin('not nice');
                 };                                print $kido->ask_for_pin('nice');
             bless($closure, $class);
             return $closure;
        };




●
    “Inside-out” classes not handy... “There is only one way to do it...” .
What OOP features offers Perl?
                                      {
{                                     package Mom;
package Mom;                              (...)
    (...)
                                          sub _prepare_pastry{
    my $_prepare_pastry = sub{               if (caller ne __PACKAGE__){
        print "makin' pastry 2 n";              die;
        };                                   }
                                             else {
    sub make_cookies{                            print "makin' pastry n";
        &{$_pastry};                         }
        print "cookies readyn";          }
        }
}
                                          sub make_cookies{
                                             _prepare_pastry();
package main;
                                             print "cookies readyn";
(...)
                                             }
package main;
                                      }
my $mom = Mom->new();
                                      package main;
$mom->make_cookies();
                                      (...)
                                      my $mom = Mom->new();
                                      $mom->_prepare_pastry(); #this
                                      compiles!
                                      $mom->make_cookies();
What OOP features offers Perl?
●    Aggregation


    package Person;                         my $eva = Person->new();
                                            my $car1 = Car->new();
     sub new {                              $car1->brand( 'Fiat' );
       my $class = shift;
       my $self = {};                       $eva->cars->[0]->brand(); #returns 'Fiat'
       $self->{'cars'} = ();
       bless( $self, $class );
       return $self;
     }

     sub cars {
       my $self = shift;
       my $car = shift;
       if ( ref( $car ) eq 'Car' ) {
         push @{ $self->{'cars'} }, $car;
       }
       return $self->cars;
     }
What OOP features offers Perl?
●   Inheritance (multi-object) and polymorphism: use base()

package Person;                                     package Employee;

sub new {                                           use base qw(Person);
        my $class = shift;
        my $self = {};                              sub new {
                                                      my $class = shift;
        bless( $self, $class );                       my $job   = shift;
        return $self;                                 my $self = $class->SUPER::new();
}                                                     $self->{'job'} = $job;

sub name {                                              bless( $self, $class );
  my $self = shift;                                     return $self;
  if ( @_ ) { $self->{'name'} = shift }             }
  return $self->{'name'};
}                                                   #overriding
                                                    sub say_name {
sub say_name {                                        my $self = shift;
  my $self = shift;                                   $self->SUPER::say_name();
  printf( "My name is %s. n", $self->{'name'} );     printf( "My job is %s.n", $self->{'job'} );
}                                                     }

                                                    #inheritance and polymorphism
                                                    my $adam = Employee->new( 'Developer' );
                                                    $adam->name( 'Adam' );
                                                    $adam->say_name
What OOP features offers Perl?
●   Abstraction – only objects
    package File;                           my $bmp = BMP->new();
      use Carp;                             $bmp->load();

      sub new {                             my $jpg = JPG->new();
        my $class = shift;                  $jpg->load();
        my $self = {};
        bless ($self, $class);
        return $self;
      }

      sub load{
        croak('not implemented');
      }

    package BMP;
      use base qw(File);

    package JPG;
      use base qw(File);

      sub load{
        my $self = shift;
        print "File loaded. n";
      }
What OOP features offers Perl?




What is missing?
●   The in-language support for OO features is minimal.
●   No type checking, no horizontal inheritance, no encapsulation...




              There is more than one way to do it!
Moose




There is more than one way to do it, but sometimes
       consistency is not a bad thing either!
Moose is Perl.




       Moose =
Class::MOP + semantic
Moose is Perl.

●   common system for building classes
●   new levels of code reuse, allowing you to improve your
code with features that would otherwise be too complex or
expensive to implement
Moose is Perl.
Everything missing in OO Perl you can find in Moose + some
important bonuses!

  ●   Type matching
  ●   Coercion - the ability to convert types of one type to another when
  necessary
  ●   Encapsulation
  ●   Method Modifiers - the ability to add code that runs before, after or
  around an existing method
  ●   Horizontal inheritance - roles - the ability to add predefined
  functionality to classes without sub-classing


… and much more.
Moose – first example.
                                                              Sets strict and warnings
              package Vehicle;
              use Moose;
MOOSE CLASS




              has 'RegNum' => (                                   Class attributes.
                      'is' => 'rw',
                      'isa' => 'Str');

              sub goto{
                  my $self = shift;                                Class methods.
                  my $place_name = shift;
                  print "Going to $place_name n";
                  }

              __PACKAGE__->meta->make_immutable;

              no Moose;
              1;




              use Vehicle;                                   We get new() for free
              my $avehicle = Vehicle->new();

              $acar->RegNum('123456');
              print $acar->RegNum;
                                                               We get also default
              $acar->goto('Oriente');
                                                               accessors for free.
Moose – first example.
12 lines of code from previous slide give us all this:
 package Vehicle;
 use strict;

 sub new {
     my $class = shift;
     my %args = @_;

      my $self   = { '_RegNum' => undef };

      if ( exists( $args{'RegNum'} ) && defined( $args{'RegNum'} ) ) {
          $self->{'_RegNum'} = $args{'RegNum'};
      }

      return bless($self, $class);
 }                                                                       package Vehicle;
                                                                         use Moose;
 sub RegNum {
     my $self   = shift;                                                 has 'RegNum' => (
     my $regnum = shift;                                                         'is' => 'rw',
     if ( $regnum ) {                                                            'isa' => 'Str');
         $self->{'_RegNum'} = $regnum;
     }                                                                   sub goto{
     return $self->{'_RegNum'};                                              my $self = shift;
 }                                                                           my $place_name = shift;
                                                                             print "Going to $place_name n";
 sub goto{                                                                   }
     my $self = shift;
     my $place_name = shift;                                             no Moose;
     print "Going to $place_name n";                                    1;
 }

 1;
Lets have a closer look...
●   Arguments


    (...)                                  'rw' or 'ro' – tells which accessors will be created

    has 'RegNum' => (
            'is' => 'rw',
            'isa' => 'Str'
    );
                                                              Moose types:
    (...)
                                                  Bool, Str, Num, Int, ArrayRef, HashRef,
                                                                and more




'is' – defines if argument is read-write or read-only
'isa' – defines type of the attribute (and validate it during assignment)
Lets have a closer look...
●   Read- only arguments

    has 'RegNum' => (                      If we restrict access to the attribute...
            'is' => 'ro',                 the default accessor won't be created.
            'isa' => 'Str'
    );

                                                 This method doesn't exist
    $avehicle->RegNum('123456');              – it results in compilation error



                                          The only right moment to set up the
    my $avehicle = Vehicle->new(            attribute is during initialization.

         'RegNum'=>'1234'

    );
                                         We can still read it wherever we want.
    print $avehicle->RegNum."n";
What more we can do with attributes?
●   Required arguments
                                                      Required attribute must be set.
                                                             It means that...
has 'RegNum' => (
        'is' => 'ro',
        'isa' => 'Str',
        'required' => 1,
        );
                                                           … this will not compile

#$acar = Vehicule->new();


my $avehicle = Vehicle->new('RegNum'=>'123456');   ...but we still can have illegal vehicle..
                                                     RegNum can be set to empty string.
my $avehicle = Vehicle->new('RegNum'=>'');




has 'RegNum' => (
        'is' => 'ro',
        'required' => 1,
        );
                                                                      BUT
my $avehicle = Vehicle->new('RegNum'=>undef);
                                                      If attribute has no type it can be
                                                               set to undefined
What more we can do with attributes?
●Clearer and predicate
Imagine... the vehicle is a broken and is waiting to be scraped, but first you must unregister it .


has 'RegNum' => (
        'is' => 'ro',                                   You can't use accessors because it is “ro”.
        'isa' => 'Str',
        'required'=> 1,
        'clearer' => 'unregister',
                                                       but... you can set clearer to clean the value
        'predicate'=>'is_registered',
        );

                                                             and predicate to check if the
                                                                     value exists
my $avehicle = Vehicule->new('RegNum'=>'1234');

print $avehicle->RegNum;

$avehicle->unregister();

if (!$avehicle->is_registered()){                                The method you get for free.
    print "Vehicle illegal!.n";
    }
What more we can do with attributes?
 ●   Subtypes
Not every string can be the registration number...

 package Vehicle;                                                use TypeConstraints
 use Moose;                                                       and create subtype
 use Moose::Util::TypeConstraints;

 subtype 'RegistrationNo'
         => as 'Str',                                                       parent type
         => where { /^(dd)(-)(ww)(-)(dd)$/ },
         => message {"$_ is not valid registration number."};


 has 'RegNum' => (                                              compare $_ to something
         'is' => 'ro',
         'isa' => 'RegistrationNo',
         'required'=> 1,
         'clearer' => 'unregister',                                     and use it
         'predicate'=>'is_registered',
         );



my $avehicle = Vehicle->new('RegNum'=>'11-xx-22');               Subtypes can be more complex
                                                                      more examples here
#my $avehicle = Vehicle->new('RegNum'=>'111-xx-22');
One Step Further - MooseX.
  ●   Custom types
Lets define where is our vehicle.... a 2D coordinate - two points: x and y that
must have positive value.


package MyTypes;
                                                                           what we want to create
use Moose;
use MooseX::Types -declare => [qw(Coordinate Point)];
use MooseX::Types::Moose qw(Int HashRef);
                                                                                  what we use to create

subtype Point,
    as Int,                                                                                 a point
    where { $_>= 0},
    message {'Must be positive number.'};


                                                    A coordinate that is a has of two valid points
subtype Coordinate,
    as HashRef,
    where { Point->check( $_->{'X'} ) and Point->check( $_->{'Y'} )},
    message {'Incorect coordinate.'.$_ };



 This is very useful type. We can pack it in separate package and reuse later.
One Step Further - MooseX.
 ●Custom types
Lets use the coordinate to define where is the vehicle.

 use MyTypes qw( Coordinate );
                                                             import custom type

 (...)
 has 'place' => (                                          modify the vehicle class
     'is' => 'rw',
     'isa' => Coordinate,
                                                                (Vehicle.pm)
 );
 (...)




 my $place = {'X'=>1, 'Y'=>3 };

 $avehicle->place( $place );

                                                          use it where ever you need
One Step Further - MooseX.
 ●   Custom types and coercion
                                                                           In the end, in class definition,
But maybe it would be easier to use it this way...?                         Don't forget to turn on the
                                                                             coercion on the argument
 $avehicle->place( [4,5] );

package MyTypes;
use Moose;
use MooseX::Types -declare => [qw(Coordinate Point)];
use MooseX::Types::Moose qw(Int HashRef ArrayRef);
subtype Point,
    as Int,
                                                                          (...)
    where { $_> 0},                                                       has 'place' => (
    message {'Must be positive number.'};                                     'is' => 'rw',
                                                                              'isa' => Coordinate,
                                                                              'coerce' => 1,
subtype Coordinate,
                                                                          );
    as HashRef,
    where { Point->check( $_->{'X'} ) and Point->check( $_->{'Y'} )},
    message {'Incorect coordinate.'.$_ };                                 (...)


coerce Coordinate,
    from ArrayRef,
    via {
        {'X'=>$_->[0], 'Y'=>$_->[1]}
    };
                                                                            We define how we can
                                                                        transform one type to another.
1;
Private attributes – only convention.
 The vehicle may change its place only when it moves ?

(...)                                                                    This is what the manual says
#an attribute to be publicly readable, but only privately settable.     – but this is only CONVENTION.
has '_place' => (
    'is' => 'ro',
    'isa' => Coordinate,
    'coerce' => 1,
    'writer' => '_set_place',
      );                                                              reader and writer redefine the
                                                                        names of custom accessors
sub goto{
    my $self = shift;
    my $coordinate = shift;
    $self->_set_place($coordinate);
}                                                                 Now we can “move” the vehicle.

(...)

$avehicle->goto([7,8]);
print Dumper($avehicle);
print 'The vehicle is at'.$avehicle->_place->{'X'}.','.$avehicle->_place-
>{'Y'}.'.';

#my $place = {'X'=>1, 'Y'=>3 };                                        However this still would work.
#my $other_place = [4,5];                                                   MOOSE is PERL
#$avehicle->_set_place( $place );
Method modifiers
Mileage – every time the vehicle moves its mileage increase.

 has '_mileage' => (                                                              One more
         'is' => 'ro',
         'isa' => 'Num',
                                                                               private attribute.
         'required' => 1,
         'default' => 0,
         'writer' => '_set_mileage',
         );                                               Method modifier


                                                                              Has access to attributes,
 around 'goto' => sub {                                                     before they are modified by
     my $orig = shift;
     my $self = shift;                                                                method
      my $coordinate1 = $self->_place;
      my $x1 = $coordinate1->{'X'};
      my $y1 = $coordinate1->{'Y'};
                                                               Executing main method
      #@_ stores new coordinate
      $self->$orig(@_);

      my $coordinate2 = $self->_place;
      my $x2 = $coordinate2->{'X'};
                                                                              Accessing modified
      my $y2 = $coordinate2->{'Y'};                                               attributes
      my $distance = sqrt(($x1-$x2)**2+($y1-$y2)**2);

      $self->_set_mileage($self->_mileage + $distance);                                      other actions
 };
Method modifiers
Mileage – every time the vehicle moves its mileage increase.




                                                   Define default value
  has '_place' => (
      'is' => 'ro',
      'isa' => Coordinate,
      'coerce' => 1,
      'writer' => '_set_place',
      'default' => sub {[0,0]},
      );




  print $avehicle->_mileage;
                                                         Every time we move vehicle
  $avehicle->goto([7,8]);
  $avehicle->goto([1,1]);                                   the mileage increase.
  $avehicle->goto([4,5]);

  print $avehicle->_mileage
Lazy, lazy_build and trigger.
Imagine we want to sell the vehicle. The price depends on the mileage.

                                                          Lazy - value is calculated only when
    has 'price' => (
            'is' => 'ro',                                      it is accessed and is unset.
            'isa' => 'Num',
            'predicate'=>'has_price',
            'lazy_build'=>1,
            'builder'=>'calculate_price',                          lazy + clearer = lazy_build
            'init_arg'=>undef,
            );


    sub calculate_price {                                  Lazy needs default value or builder
        my $self = shift;
        my $price = 100000;
        if ($self->_mileage != 0){
            $price = $price / $self->_mileage;
        }
        return $price;                                           Method building the value.
    }



    $avehicle->goto([1,1]);
                                                    ...despite we move, the price didn't change.
    print $avehicle->price;
                                                 Lazy build calculates the value only if it is unset.
    $avehicle->goto([4,5]);                           Therefore we need to clean it every time
                                                            we want to get updated value.
    print $avehicle->price;
Lazy, lazy_build and trigger.
Let's run the clearer automatically.

 has '_mileage' => (
                                                               Every time the mileage changes the
         'is' => 'ro',                                         clearer for price attribute is triggered.
         'isa' => 'Num',
         'required' => 1,
         'default' => 0,
         'writer' => '_set_mileage',
         'trigger' => sub {
             my $self=shift;
                                                         After this change the previous example
             $self->clear_price;                       shows updated value every time we access it
             }
         );


Lazy build is very useful for attributes are expensive to calculate –
we calculate it only while reading.
 sub sell_vehicle {
     my $self = shift;
     $self->clear_price;
     return $self->price;                               We can also use method instead the trigger.
     }
                                                         The price is updated every time we read it
 $avehicle->goto([1,1]);                                              using the method.
 print $avehicle->price;
                                                              Useful for expensive calculation.
 $avehicle->goto([4,5]);
 print $avehicle->price;

 print "The final price: ".$avehicle->sell_vehicle. "n";
Code reuse - inheritance in Moose.
Is the vehicle car or bike?

package Car;
use Moose;
                                                   Parent class
extends 'Vehicle';

has 'fuel' =>(
    'is' => 'rw',
    'isa' => 'Int',
    'default'=>0,                             New attribute
);

sub refuel {
    my $self = shift;
    $self->fuel($self->fuel + 10);              New method
    }

override goto => sub{
    my $self = shift;
                                            Overwritten method
     if($self->fuel eq 0){
         print 'No fuel';
         return;
     }
     return super;
};
                                                    Calling super

no Moose
Code reuse - inheritance in Moose.


package Bike;
use Moose;

extends 'Vehicle';

has '+RegNum' => (
    'required'=> 0,
    );                              changing inherited attribute
no Moose;
1;




my $abike = Bike->new();   registration number is not linger required
Better code reuse – inheritance and roles.
Short explanation:

●   Role is a “state or behavior that can be shared between classes.”

●   Role is not a class – can't be subclassed, can't be extended … we can't create an object of a role .

●   But we can use a role in a class, and methods of the role in an object.
Better code reuse – inheritance and roles.
We can create a 'truck' role and use it in our vehicle.
                                                           The only difference


     package Truck;                           sub do_load {
     use Moose::Role;                             my $self = shift;
                                                  my $load = shift;
     has 'capacity' => (
         'is' => 'ro',                            if(($self->capacity >= $load) and !$self->load){
         'isa' => 'Int',                            $self->load(1);
         'default'=>10,                           }else{
         'required'=>1,                             print 'Load unsuccessful,';
     );                                           }
                                              }

     has 'load' => (                          sub do_unload {
         'is' => 'rw',                            my $self = shift;
         'isa' => 'Bool',                         my $load = shift;
         'default'=>0,
     );                                           if($self->load){
                                                    $self->load(0);
                                                  }else{
                                                    print 'Nothing to unload,';
                                                  }
                                              }
We create a piece of functionality            no Moose;
                                              1;
exactly the same way as we were
     creating a moose class.
Better code reuse – inheritance and roles.
We want to have a car with a “truck functionality” - a lorry.
 package Lorry;
 use Moose;

 extends 'Car';
 with 'Truck';
                                                                  Lorry = Car with Truck role

 no Moose;
 1;


 How to use Lorry?                           Lorry is a vehicle – mast have registration number.
 (…)

 use Lorry;

 (…)
                                                            Lorry has a Truck role – mast have capacity.


 my $alorry = Lorry->new('RegNum'=>'11-xx-23', 'capacity'=>50);
 #$alorry->do_load(100); - more than capacity

 $alorry->do_load(40);
 #$alorry->do_load(40); #unsecessfull - is loaded
                                                                       We can use all truck functions.
 $alorry->do_unload();
 $alorry->do_load(30);

 #$alorry->goto([2,4]); - still can't go without the fuel
                                                                              But Lorry is still a car
                                                                             so won't go without fuel.
Better code reuse – inheritance and roles.
In the end we want to assure that the truck role will be only used with anything that uses fuel
(Have you ever seen a lorry-bike?)

  package Truck;
  use Moose::Role;
                                                                 We require that a method 'fuel'
  requires 'fuel';                                               is present in a class where we
                                                                       use the Truck role.
  (…)


  use Moose;

  extends 'Bike';
  with 'Truck';

  no Moose;                                                   Since bike doesn't use fuel
                                                              this code will not compile.



  'Truck' requires the method 'fuel' to be implemented by 'Lorrybike' at
  /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi/Moose/Meta/Role/Application.pm line 51
        Moose::Meta::Role::Application::apply('Moose::Meta::Role::Application::ToClass=HASH(0xa5faa2c)',
  'Moose::Meta::Role=HASH(0xa5f6a6c)', 'Moose::Meta::Class=HASH(0xa5f8754)') called at
  /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi/Moose/Meta/Role/Application/ToClass.pm
  line 31
  (...)
BUILDARGS and BUILD
Let's go back to Vehicle. It would be awesome to create a vehicle this way :

 $acar = Vehicule->new('11-xx-11');




                                                 BUILDARGS method is called as a class method
 around BUILDARGS => sub {
                                                 before an object is created. It has direct access
     my $orig = shift;                                to arguments passed in method call.
     my $class = shift;

      my %a = @_;
      my %args = ();
      if ( @_ == 1 ) {
         $args{ 'RegNum' } = $_[0];
         return $class->$orig( %args );
      }
      return $class->$orig( %a );
 };
BUILDARGS and BUILD

There is a possibility to have a bike without registration. But we want to be warn about it...




                                                 BUILD method is called after an object is created.
   sub BUILD {
       my $self = shift;
           if(!$self->RegNum){
               if($self->isa('Bike')){
                   print "Vehicle without registration number.n";
                   }
               }
       }
                                                              We will be warn about creating a
                                                             bike without a registration number.



   my $abike = Bike->new();
   my $abike2 = Bike->new('22-yy-66');
Aggregation and Native Traits
Let's create a garage for our vehicles.


  package Garage;                                                    Notice: there is no
  use Moose;
  use Moose::Util::TypeConstraints;                                      'is' =>'ro|rw'


  has 'vehicles' => (
      'isa'=> 'ArrayRef[ Vehicle ]',
      'default' => sub {[]},
      'traits' => ['Array'],
      'handles'=> {
                                                               Trait – a role added to attribute.
          'add_vehicle' => 'push',                           Here we make the vehicles attribute
          'get_vehicle' => 'shift',                                    work as an array.
          },
  );

  no Moose;
  1;
                                                                      Defining accessors.
                                                             (these accessors use type checking).
More native traits:
Array: push, pop, shift, unshit, map, sort, grep …
Hash: get, set, delete, exists, defined, clear, is_empty …
String: append, substr, length...
Bool: set, unset, toggle...
Code: execute, execute_method...
Aggregation and Native Traits
Let's park some vehicles...



  my $garage = Garage->new();

  $garage->add_vehicle($avehicle);
  my $v = $garage->get_vehicle();

  $garage->add_vehicle($acar);
  my $acar2 = $garage->get_vehicle();




                                         $acar2 and $acar is the same
                                        (reference to the same object)
What more you can do in Moose?

For example:

●   Delegation - "proxy" methods call some other method on an
    attribute.

●   Custom traits - MooseX

●   Custom OO system – sub-classing methaclasses

●   And much more...
Some tips
●   If you don't know what is wrong try to load package from command line :

                       perl -Ilib/ -e 'use Coordinate'

●   $object->dump for debugging
More information:

●   http://www.oscon.com/oscon2010/public/schedule/detail/13673
    Moose is Perl: A Guide to the New Revolution

http://www.slideshare.net/dtreder/moose-527243
●


Awesome presentation with huge dose of humor, but also very helpful.

http://search.cpan.org/~drolsky/Moose-1.21/
●


Moose::Manual and Moose::Cookbook

Weitere ähnliche Inhalte

Was ist angesagt?

WordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressWordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressAlena Holligan
 
(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Rolessartak
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helperslicejack
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perlgarux
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindiappsdevelopment
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Shortcodes In-Depth
Shortcodes In-DepthShortcodes In-Depth
Shortcodes In-DepthMicah Wood
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5Jason Austin
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryl3rady
 
Bioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekingeBioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekingeProf. Wim Van Criekinge
 
Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13Rafael Dohms
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Coffeescript: No really, it's just Javascript
Coffeescript: No really, it's just JavascriptCoffeescript: No really, it's just Javascript
Coffeescript: No really, it's just JavascriptBrian Mann
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 

Was ist angesagt? (20)

Coffee Script
Coffee ScriptCoffee Script
Coffee Script
 
WordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressWordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPress
 
(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Roles
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helper
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in php
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Shortcodes In-Depth
Shortcodes In-DepthShortcodes In-Depth
Shortcodes In-Depth
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know query
 
Bioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekingeBioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekinge
 
Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13Your code sucks, let's fix it! - php|tek13
Your code sucks, let's fix it! - php|tek13
 
Bioinformatica p6-bioperl
Bioinformatica p6-bioperlBioinformatica p6-bioperl
Bioinformatica p6-bioperl
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Coffeescript: No really, it's just Javascript
Coffeescript: No really, it's just JavascriptCoffeescript: No really, it's just Javascript
Coffeescript: No really, it's just Javascript
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Smelling your code
Smelling your codeSmelling your code
Smelling your code
 

Ähnlich wie Introduction to Moose

What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16Ricardo Signes
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
Perl from the ground up: objects and testing
Perl from the ground up: objects and testingPerl from the ground up: objects and testing
Perl from the ground up: objects and testingShmuel Fomberg
 
Advanced modulinos
Advanced modulinosAdvanced modulinos
Advanced modulinosbrian d foy
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable PluginBrandon Dove
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev AssistantDave Cross
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix itRafael Dohms
 
究極のコントローラを目指す
究極のコントローラを目指す究極のコントローラを目指す
究極のコントローラを目指すYasuo Harada
 

Ähnlich wie Introduction to Moose (20)

mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
wget.pl
wget.plwget.pl
wget.pl
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16
 
OOP in PHP.pptx
OOP in PHP.pptxOOP in PHP.pptx
OOP in PHP.pptx
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Perl from the ground up: objects and testing
Perl from the ground up: objects and testingPerl from the ground up: objects and testing
Perl from the ground up: objects and testing
 
Presentation1
Presentation1Presentation1
Presentation1
 
DBI
DBIDBI
DBI
 
Advanced modulinos
Advanced modulinosAdvanced modulinos
Advanced modulinos
 
Perl object ?
Perl object ?Perl object ?
Perl object ?
 
Oops in php
Oops in phpOops in php
Oops in php
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable Plugin
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev Assistant
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
究極のコントローラを目指す
究極のコントローラを目指す究極のコントローラを目指す
究極のコントローラを目指す
 

Kürzlich hochgeladen

SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 

Kürzlich hochgeladen (20)

SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 

Introduction to Moose

  • 2. What we expect from OOP ● Classes (methods, types, attributes, open recursion...) ● Encapsulation ● Aggregation ● Message passing and dynamic dispatch ● Inheritance and polymorphism ● Abstraction Skip definitions
  • 3. Classes ● Templates for defining objects state and behavior
  • 4. Encapsulation ● Specifying which classes may use the members of an object e.g: public, protected or private, determining whether they are available to all classes, sub-classes or only the defining class.
  • 5. Aggregation ● Object containing another object
  • 6. Message passing and dynamic dispatch ● Message passing is the process by which an object sends data to another object or asks the other object to invoke a method ● when a method is invoked on an object, the object itself determines what code gets executed by looking up the method at run time in a table associated with the object (needed when multiple classes contain different implementations of the same method )
  • 7. Inheritance and polymorphism ● allows the programmer to treat derived class members just like their parent class's members ("Subclasses" are more specialized versions of a class, which inherit attributes and behaviors from their parent classes, and can introduce their own.) ● a class has all the state and behavior of another class - polymorphism
  • 8. What OOP features offers Perl? ● MOP in Perl5: ● Class - package ● Object - blessed reference (a scalar type holding a reference to object data – object may be a hash, array, or reference to subroutine.) ● Method - a subroutine within a package ● Constructor – a method that returns reference to blessed variable
  • 9. What OOP features offers Perl? package Car; sub new { my $class = shift; my $brand = shift; my $self = {}; $self->{'brand'} = $brand; bless ($self, $class); return $self; }
  • 10. What OOP features offers Perl? ● Encapsulation – in general only by convention. ● Some tricks: private variable, private method, private function package Mom; package Kido; sub new{ use base qw(Mom); my $class = shift; my $self = { sub ask_for_pin{ 'CARD_PIN' => '0000', my $self = shift; }; my $how = shift; return &{$self}($how); my $closure = sub { } my $arg = shift; if ($arg and $arg eq 'nice'){ return $self->{'CARD_PIN'}; package main; } my $mom = Mom->new(); else { my $kido = Kido->new(); return 'forget!'; } print $kido->ask_for_pin('not nice'); }; print $kido->ask_for_pin('nice'); bless($closure, $class); return $closure; }; ● “Inside-out” classes not handy... “There is only one way to do it...” .
  • 11. What OOP features offers Perl? { { package Mom; package Mom; (...) (...) sub _prepare_pastry{ my $_prepare_pastry = sub{ if (caller ne __PACKAGE__){ print "makin' pastry 2 n"; die; }; } else { sub make_cookies{ print "makin' pastry n"; &{$_pastry}; } print "cookies readyn"; } } } sub make_cookies{ _prepare_pastry(); package main; print "cookies readyn"; (...) } package main; } my $mom = Mom->new(); package main; $mom->make_cookies(); (...) my $mom = Mom->new(); $mom->_prepare_pastry(); #this compiles! $mom->make_cookies();
  • 12. What OOP features offers Perl? ● Aggregation package Person; my $eva = Person->new(); my $car1 = Car->new(); sub new { $car1->brand( 'Fiat' ); my $class = shift; my $self = {}; $eva->cars->[0]->brand(); #returns 'Fiat' $self->{'cars'} = (); bless( $self, $class ); return $self; } sub cars { my $self = shift; my $car = shift; if ( ref( $car ) eq 'Car' ) { push @{ $self->{'cars'} }, $car; } return $self->cars; }
  • 13. What OOP features offers Perl? ● Inheritance (multi-object) and polymorphism: use base() package Person; package Employee; sub new { use base qw(Person); my $class = shift; my $self = {}; sub new { my $class = shift; bless( $self, $class ); my $job = shift; return $self; my $self = $class->SUPER::new(); } $self->{'job'} = $job; sub name { bless( $self, $class ); my $self = shift; return $self; if ( @_ ) { $self->{'name'} = shift } } return $self->{'name'}; } #overriding sub say_name { sub say_name { my $self = shift; my $self = shift; $self->SUPER::say_name(); printf( "My name is %s. n", $self->{'name'} ); printf( "My job is %s.n", $self->{'job'} ); } } #inheritance and polymorphism my $adam = Employee->new( 'Developer' ); $adam->name( 'Adam' ); $adam->say_name
  • 14. What OOP features offers Perl? ● Abstraction – only objects package File; my $bmp = BMP->new(); use Carp; $bmp->load(); sub new { my $jpg = JPG->new(); my $class = shift; $jpg->load(); my $self = {}; bless ($self, $class); return $self; } sub load{ croak('not implemented'); } package BMP; use base qw(File); package JPG; use base qw(File); sub load{ my $self = shift; print "File loaded. n"; }
  • 15. What OOP features offers Perl? What is missing? ● The in-language support for OO features is minimal. ● No type checking, no horizontal inheritance, no encapsulation... There is more than one way to do it!
  • 16. Moose There is more than one way to do it, but sometimes consistency is not a bad thing either!
  • 17. Moose is Perl. Moose = Class::MOP + semantic
  • 18. Moose is Perl. ● common system for building classes ● new levels of code reuse, allowing you to improve your code with features that would otherwise be too complex or expensive to implement
  • 19. Moose is Perl. Everything missing in OO Perl you can find in Moose + some important bonuses! ● Type matching ● Coercion - the ability to convert types of one type to another when necessary ● Encapsulation ● Method Modifiers - the ability to add code that runs before, after or around an existing method ● Horizontal inheritance - roles - the ability to add predefined functionality to classes without sub-classing … and much more.
  • 20. Moose – first example. Sets strict and warnings package Vehicle; use Moose; MOOSE CLASS has 'RegNum' => ( Class attributes. 'is' => 'rw', 'isa' => 'Str'); sub goto{ my $self = shift; Class methods. my $place_name = shift; print "Going to $place_name n"; } __PACKAGE__->meta->make_immutable; no Moose; 1; use Vehicle; We get new() for free my $avehicle = Vehicle->new(); $acar->RegNum('123456'); print $acar->RegNum; We get also default $acar->goto('Oriente'); accessors for free.
  • 21. Moose – first example. 12 lines of code from previous slide give us all this: package Vehicle; use strict; sub new { my $class = shift; my %args = @_; my $self = { '_RegNum' => undef }; if ( exists( $args{'RegNum'} ) && defined( $args{'RegNum'} ) ) { $self->{'_RegNum'} = $args{'RegNum'}; } return bless($self, $class); } package Vehicle; use Moose; sub RegNum { my $self = shift; has 'RegNum' => ( my $regnum = shift; 'is' => 'rw', if ( $regnum ) { 'isa' => 'Str'); $self->{'_RegNum'} = $regnum; } sub goto{ return $self->{'_RegNum'}; my $self = shift; } my $place_name = shift; print "Going to $place_name n"; sub goto{ } my $self = shift; my $place_name = shift; no Moose; print "Going to $place_name n"; 1; } 1;
  • 22. Lets have a closer look... ● Arguments (...) 'rw' or 'ro' – tells which accessors will be created has 'RegNum' => ( 'is' => 'rw', 'isa' => 'Str' ); Moose types: (...) Bool, Str, Num, Int, ArrayRef, HashRef, and more 'is' – defines if argument is read-write or read-only 'isa' – defines type of the attribute (and validate it during assignment)
  • 23. Lets have a closer look... ● Read- only arguments has 'RegNum' => ( If we restrict access to the attribute... 'is' => 'ro', the default accessor won't be created. 'isa' => 'Str' ); This method doesn't exist $avehicle->RegNum('123456'); – it results in compilation error The only right moment to set up the my $avehicle = Vehicle->new( attribute is during initialization. 'RegNum'=>'1234' ); We can still read it wherever we want. print $avehicle->RegNum."n";
  • 24. What more we can do with attributes? ● Required arguments Required attribute must be set. It means that... has 'RegNum' => ( 'is' => 'ro', 'isa' => 'Str', 'required' => 1, ); … this will not compile #$acar = Vehicule->new(); my $avehicle = Vehicle->new('RegNum'=>'123456'); ...but we still can have illegal vehicle.. RegNum can be set to empty string. my $avehicle = Vehicle->new('RegNum'=>''); has 'RegNum' => ( 'is' => 'ro', 'required' => 1, ); BUT my $avehicle = Vehicle->new('RegNum'=>undef); If attribute has no type it can be set to undefined
  • 25. What more we can do with attributes? ●Clearer and predicate Imagine... the vehicle is a broken and is waiting to be scraped, but first you must unregister it . has 'RegNum' => ( 'is' => 'ro', You can't use accessors because it is “ro”. 'isa' => 'Str', 'required'=> 1, 'clearer' => 'unregister', but... you can set clearer to clean the value 'predicate'=>'is_registered', ); and predicate to check if the value exists my $avehicle = Vehicule->new('RegNum'=>'1234'); print $avehicle->RegNum; $avehicle->unregister(); if (!$avehicle->is_registered()){ The method you get for free. print "Vehicle illegal!.n"; }
  • 26. What more we can do with attributes? ● Subtypes Not every string can be the registration number... package Vehicle; use TypeConstraints use Moose; and create subtype use Moose::Util::TypeConstraints; subtype 'RegistrationNo' => as 'Str', parent type => where { /^(dd)(-)(ww)(-)(dd)$/ }, => message {"$_ is not valid registration number."}; has 'RegNum' => ( compare $_ to something 'is' => 'ro', 'isa' => 'RegistrationNo', 'required'=> 1, 'clearer' => 'unregister', and use it 'predicate'=>'is_registered', ); my $avehicle = Vehicle->new('RegNum'=>'11-xx-22'); Subtypes can be more complex more examples here #my $avehicle = Vehicle->new('RegNum'=>'111-xx-22');
  • 27. One Step Further - MooseX. ● Custom types Lets define where is our vehicle.... a 2D coordinate - two points: x and y that must have positive value. package MyTypes; what we want to create use Moose; use MooseX::Types -declare => [qw(Coordinate Point)]; use MooseX::Types::Moose qw(Int HashRef); what we use to create subtype Point, as Int, a point where { $_>= 0}, message {'Must be positive number.'}; A coordinate that is a has of two valid points subtype Coordinate, as HashRef, where { Point->check( $_->{'X'} ) and Point->check( $_->{'Y'} )}, message {'Incorect coordinate.'.$_ }; This is very useful type. We can pack it in separate package and reuse later.
  • 28. One Step Further - MooseX. ●Custom types Lets use the coordinate to define where is the vehicle. use MyTypes qw( Coordinate ); import custom type (...) has 'place' => ( modify the vehicle class 'is' => 'rw', 'isa' => Coordinate, (Vehicle.pm) ); (...) my $place = {'X'=>1, 'Y'=>3 }; $avehicle->place( $place ); use it where ever you need
  • 29. One Step Further - MooseX. ● Custom types and coercion In the end, in class definition, But maybe it would be easier to use it this way...? Don't forget to turn on the coercion on the argument $avehicle->place( [4,5] ); package MyTypes; use Moose; use MooseX::Types -declare => [qw(Coordinate Point)]; use MooseX::Types::Moose qw(Int HashRef ArrayRef); subtype Point, as Int, (...) where { $_> 0}, has 'place' => ( message {'Must be positive number.'}; 'is' => 'rw', 'isa' => Coordinate, 'coerce' => 1, subtype Coordinate, ); as HashRef, where { Point->check( $_->{'X'} ) and Point->check( $_->{'Y'} )}, message {'Incorect coordinate.'.$_ }; (...) coerce Coordinate, from ArrayRef, via { {'X'=>$_->[0], 'Y'=>$_->[1]} }; We define how we can transform one type to another. 1;
  • 30. Private attributes – only convention. The vehicle may change its place only when it moves ? (...) This is what the manual says #an attribute to be publicly readable, but only privately settable. – but this is only CONVENTION. has '_place' => ( 'is' => 'ro', 'isa' => Coordinate, 'coerce' => 1, 'writer' => '_set_place', ); reader and writer redefine the names of custom accessors sub goto{ my $self = shift; my $coordinate = shift; $self->_set_place($coordinate); } Now we can “move” the vehicle. (...) $avehicle->goto([7,8]); print Dumper($avehicle); print 'The vehicle is at'.$avehicle->_place->{'X'}.','.$avehicle->_place- >{'Y'}.'.'; #my $place = {'X'=>1, 'Y'=>3 }; However this still would work. #my $other_place = [4,5]; MOOSE is PERL #$avehicle->_set_place( $place );
  • 31. Method modifiers Mileage – every time the vehicle moves its mileage increase. has '_mileage' => ( One more 'is' => 'ro', 'isa' => 'Num', private attribute. 'required' => 1, 'default' => 0, 'writer' => '_set_mileage', ); Method modifier Has access to attributes, around 'goto' => sub { before they are modified by my $orig = shift; my $self = shift; method my $coordinate1 = $self->_place; my $x1 = $coordinate1->{'X'}; my $y1 = $coordinate1->{'Y'}; Executing main method #@_ stores new coordinate $self->$orig(@_); my $coordinate2 = $self->_place; my $x2 = $coordinate2->{'X'}; Accessing modified my $y2 = $coordinate2->{'Y'}; attributes my $distance = sqrt(($x1-$x2)**2+($y1-$y2)**2); $self->_set_mileage($self->_mileage + $distance); other actions };
  • 32. Method modifiers Mileage – every time the vehicle moves its mileage increase. Define default value has '_place' => ( 'is' => 'ro', 'isa' => Coordinate, 'coerce' => 1, 'writer' => '_set_place', 'default' => sub {[0,0]}, ); print $avehicle->_mileage; Every time we move vehicle $avehicle->goto([7,8]); $avehicle->goto([1,1]); the mileage increase. $avehicle->goto([4,5]); print $avehicle->_mileage
  • 33. Lazy, lazy_build and trigger. Imagine we want to sell the vehicle. The price depends on the mileage. Lazy - value is calculated only when has 'price' => ( 'is' => 'ro', it is accessed and is unset. 'isa' => 'Num', 'predicate'=>'has_price', 'lazy_build'=>1, 'builder'=>'calculate_price', lazy + clearer = lazy_build 'init_arg'=>undef, ); sub calculate_price { Lazy needs default value or builder my $self = shift; my $price = 100000; if ($self->_mileage != 0){ $price = $price / $self->_mileage; } return $price; Method building the value. } $avehicle->goto([1,1]); ...despite we move, the price didn't change. print $avehicle->price; Lazy build calculates the value only if it is unset. $avehicle->goto([4,5]); Therefore we need to clean it every time we want to get updated value. print $avehicle->price;
  • 34. Lazy, lazy_build and trigger. Let's run the clearer automatically. has '_mileage' => ( Every time the mileage changes the 'is' => 'ro', clearer for price attribute is triggered. 'isa' => 'Num', 'required' => 1, 'default' => 0, 'writer' => '_set_mileage', 'trigger' => sub { my $self=shift; After this change the previous example $self->clear_price; shows updated value every time we access it } ); Lazy build is very useful for attributes are expensive to calculate – we calculate it only while reading. sub sell_vehicle { my $self = shift; $self->clear_price; return $self->price; We can also use method instead the trigger. } The price is updated every time we read it $avehicle->goto([1,1]); using the method. print $avehicle->price; Useful for expensive calculation. $avehicle->goto([4,5]); print $avehicle->price; print "The final price: ".$avehicle->sell_vehicle. "n";
  • 35. Code reuse - inheritance in Moose. Is the vehicle car or bike? package Car; use Moose; Parent class extends 'Vehicle'; has 'fuel' =>( 'is' => 'rw', 'isa' => 'Int', 'default'=>0, New attribute ); sub refuel { my $self = shift; $self->fuel($self->fuel + 10); New method } override goto => sub{ my $self = shift; Overwritten method if($self->fuel eq 0){ print 'No fuel'; return; } return super; }; Calling super no Moose
  • 36. Code reuse - inheritance in Moose. package Bike; use Moose; extends 'Vehicle'; has '+RegNum' => ( 'required'=> 0, ); changing inherited attribute no Moose; 1; my $abike = Bike->new(); registration number is not linger required
  • 37. Better code reuse – inheritance and roles. Short explanation: ● Role is a “state or behavior that can be shared between classes.” ● Role is not a class – can't be subclassed, can't be extended … we can't create an object of a role . ● But we can use a role in a class, and methods of the role in an object.
  • 38. Better code reuse – inheritance and roles. We can create a 'truck' role and use it in our vehicle. The only difference package Truck; sub do_load { use Moose::Role; my $self = shift; my $load = shift; has 'capacity' => ( 'is' => 'ro', if(($self->capacity >= $load) and !$self->load){ 'isa' => 'Int', $self->load(1); 'default'=>10, }else{ 'required'=>1, print 'Load unsuccessful,'; ); } } has 'load' => ( sub do_unload { 'is' => 'rw', my $self = shift; 'isa' => 'Bool', my $load = shift; 'default'=>0, ); if($self->load){ $self->load(0); }else{ print 'Nothing to unload,'; } } We create a piece of functionality no Moose; 1; exactly the same way as we were creating a moose class.
  • 39. Better code reuse – inheritance and roles. We want to have a car with a “truck functionality” - a lorry. package Lorry; use Moose; extends 'Car'; with 'Truck'; Lorry = Car with Truck role no Moose; 1; How to use Lorry? Lorry is a vehicle – mast have registration number. (…) use Lorry; (…) Lorry has a Truck role – mast have capacity. my $alorry = Lorry->new('RegNum'=>'11-xx-23', 'capacity'=>50); #$alorry->do_load(100); - more than capacity $alorry->do_load(40); #$alorry->do_load(40); #unsecessfull - is loaded We can use all truck functions. $alorry->do_unload(); $alorry->do_load(30); #$alorry->goto([2,4]); - still can't go without the fuel But Lorry is still a car so won't go without fuel.
  • 40. Better code reuse – inheritance and roles. In the end we want to assure that the truck role will be only used with anything that uses fuel (Have you ever seen a lorry-bike?) package Truck; use Moose::Role; We require that a method 'fuel' requires 'fuel'; is present in a class where we use the Truck role. (…) use Moose; extends 'Bike'; with 'Truck'; no Moose; Since bike doesn't use fuel this code will not compile. 'Truck' requires the method 'fuel' to be implemented by 'Lorrybike' at /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi/Moose/Meta/Role/Application.pm line 51 Moose::Meta::Role::Application::apply('Moose::Meta::Role::Application::ToClass=HASH(0xa5faa2c)', 'Moose::Meta::Role=HASH(0xa5f6a6c)', 'Moose::Meta::Class=HASH(0xa5f8754)') called at /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi/Moose/Meta/Role/Application/ToClass.pm line 31 (...)
  • 41. BUILDARGS and BUILD Let's go back to Vehicle. It would be awesome to create a vehicle this way : $acar = Vehicule->new('11-xx-11'); BUILDARGS method is called as a class method around BUILDARGS => sub { before an object is created. It has direct access my $orig = shift; to arguments passed in method call. my $class = shift; my %a = @_; my %args = (); if ( @_ == 1 ) { $args{ 'RegNum' } = $_[0]; return $class->$orig( %args ); } return $class->$orig( %a ); };
  • 42. BUILDARGS and BUILD There is a possibility to have a bike without registration. But we want to be warn about it... BUILD method is called after an object is created. sub BUILD { my $self = shift; if(!$self->RegNum){ if($self->isa('Bike')){ print "Vehicle without registration number.n"; } } } We will be warn about creating a bike without a registration number. my $abike = Bike->new(); my $abike2 = Bike->new('22-yy-66');
  • 43. Aggregation and Native Traits Let's create a garage for our vehicles. package Garage; Notice: there is no use Moose; use Moose::Util::TypeConstraints; 'is' =>'ro|rw' has 'vehicles' => ( 'isa'=> 'ArrayRef[ Vehicle ]', 'default' => sub {[]}, 'traits' => ['Array'], 'handles'=> { Trait – a role added to attribute. 'add_vehicle' => 'push', Here we make the vehicles attribute 'get_vehicle' => 'shift', work as an array. }, ); no Moose; 1; Defining accessors. (these accessors use type checking). More native traits: Array: push, pop, shift, unshit, map, sort, grep … Hash: get, set, delete, exists, defined, clear, is_empty … String: append, substr, length... Bool: set, unset, toggle... Code: execute, execute_method...
  • 44. Aggregation and Native Traits Let's park some vehicles... my $garage = Garage->new(); $garage->add_vehicle($avehicle); my $v = $garage->get_vehicle(); $garage->add_vehicle($acar); my $acar2 = $garage->get_vehicle(); $acar2 and $acar is the same (reference to the same object)
  • 45. What more you can do in Moose? For example: ● Delegation - "proxy" methods call some other method on an attribute. ● Custom traits - MooseX ● Custom OO system – sub-classing methaclasses ● And much more...
  • 46. Some tips ● If you don't know what is wrong try to load package from command line : perl -Ilib/ -e 'use Coordinate' ● $object->dump for debugging
  • 47. More information: ● http://www.oscon.com/oscon2010/public/schedule/detail/13673 Moose is Perl: A Guide to the New Revolution http://www.slideshare.net/dtreder/moose-527243 ● Awesome presentation with huge dose of humor, but also very helpful. http://search.cpan.org/~drolsky/Moose-1.21/ ● Moose::Manual and Moose::Cookbook