SlideShare une entreprise Scribd logo
1  sur  64
 
Moose
Renée Bäcker $foo – Perl-Magazin Frankfurt.pm Selbständiger Perl-Programmierer
Moose A postmodern object system for Perl 5
 
Warum Moose? ,[object Object]
Objektorientierung ist also nichts „natives“ in Perl
Dadurch ist vieles nicht so schön wie in anderen Sprachen
… vieles muss händisch gemacht werden
Warum Moose? package Employee; sub new { bless {} } for my $attr (qw(name title)) { no strict; *$attr = sub { my $self = shift; $self->{ $attr } = shift if @_; return $self->{ $attr }; }; }
Warum Moose? package Employee; sub new { bless {} } sub name { my $self = shift; $self->{name} = shift if @_; return $self->{name}; } sub title { my $self = shift; $self->{title} = shift if @_; return $self->{title}; }
Warum Moose? class Employee attr_accessor :name attr_accessor :title end
Warum Moose? package Employee; use Moose; has name  => (is => 'ro'); has title => (is => 'rw');
Warum Moose? ,[object Object]
Führt zu wartbarem, lesbarem Perl-Code
Ein Vergleich...
Elch vs. Kamel – ein Vergleich
Moose Eine Einführung
Moose – Eine Einführung ,[object Object]
-> use warnings;
-> @ISA = qw(Moose::Object) unless @ISA; ,[object Object],[object Object]
Moose - Attribute ,[object Object],has attributname => ( # … # Eigenschaften des Attributs # … );
Moose - Attribute package Event; use Moose; has 'name' => ( is => 'ro' ); no Moose; 1;
Moose - Attribute package Event; use Moose; has 'name' => ( is => 'ro' ); no Moose; 1; use Event; my $event = Event->new( name => 'FrOSCamp', ); print $event->name;
Moose - Attribute ,[object Object]
'rw' -> read/write ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Moose - Attribute has name => ( is  => 'ro', required => 1, ); has orga => ( is  => 'rw', isa  => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, );
Moose - Attribute has name => ( is  => 'ro', required => 1, ); has orga => ( is  => 'rw', isa  => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Man muss einen Namen beim Objekterzeugen angeben!
Moose - Attribute has name => ( is  => 'ro', required => 1, ); has orga => ( is  => 'rw', isa  => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Hierfür gibt es sowohl „getter“ als auch „setter“
Moose - Attribute has name => ( is  => 'ro', required => 1, ); has orga => ( is  => 'rw', isa  => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Das Attribut ist eine Arrayreferenz, in der nur Strings vorkommen dürfen.
Moose - Attribute has name => ( is  => 'ro', required => 1, ); has orga => ( is  => 'rw', isa  => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Falls bei der Erzeugung des Objekts keine orga angegeben wird, ist das der Standardwert
Moose - Typen has orga => ( is  => 'rw', isa  => 'ArrayRef[Str]' , default => sub{ [qw/Sandro Marcus/] }, ); ,[object Object]
Moose – Typen
Moose – Typen ,[object Object],has start_date => ( is  => 'rw', isa => 'DateTime' , );
Moose – Typen ,[object Object],my $event = Event->new( name  => 'FrOSCamp', start_date => DateTime->new(  year => 2010,  month => 9,  day => 17, ), );
Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str'  => where { length $_[0] <= 140 }; has twitter => ( is  => 'rw', isa  => 'ArrayRef[TwitterMsg]', auto_deref => 1, );
Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str'  => where { length $_[0] <= 140 }; has twitter => ( is  => 'rw', isa  => 'ArrayRef[TwitterMsg]', auto_deref => 1, ); Ein neuer Datentyp mit Namen „TwitterMsg“
Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' =>  as 'Str'   => where { length $_[0] <= 140 }; has twitter => ( is  => 'rw', isa  => 'ArrayRef[TwitterMsg]', auto_deref => 1,, ); …  mit „Str“ als Basis
Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str'  =>  where { length $_[0] <= 140 } ; has twitter => ( is  => 'rw', isa  => 'ArrayRef[TwitterMsg]', auto_deref => 1, ); …  und der Bedingung, dass der String kürzer als 140 Zeichen oder genau 140 Zeichen lang ist
Moose – Typen $event->twitter( [ 'hallo', 'welt' ], ); print &quot;<<$_>>&quot; for $event->twitter;
Moose – Typen $event->twitter( [ 'hallo', 'welt',  'y' x 144  ], ); print &quot;<<$_>>&quot; for $event->twitter; Attribute (twitter) does not pass the type  constraint because: Validation failed for 'ArrayRef[TwitterMsg]'
Moose – Typen my $event = Event->new( name  => 'FrOSCamp', start_date => '17.09.2010', );
Moose – Typen subtype 'DateTime' => as 'Object'  => where { $_[0]->isa( 'DateTime' ) }; coerce 'DateTime' => from 'Str'  => via {  my %info;  @info{qw/day month year/} = split //, $_; DateTime->new( %info ); }; has start_date => ( is  => 'rw', isa  => 'DateTime', coerce => 1, );
Moose – Attribute ,[object Object]
In Subklassen zusätzlich erweitern
Moose - Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } }
Moose – Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } } before send_cfp  => sub { print &quot;*vor* send_cfp&quot;; };
Moose – Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } } before send_cfp  =>  sub { print &quot;*vor* send_cfp&quot;; } ;
Moose – Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } } after send_cfp  => sub { print &quot;*nach* send_cfp&quot;; };
Moose – Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } } after send_cfp  =>  sub { print &quot;*nach* send_cfp&quot;; } ;
Moose – Methoden ,[object Object]
Man bekommt bei „before“ aber die Parameter übergeben
Moose – Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } } around send_cfp  =>  sub { my ($self,$code,@param) = @_; print &quot;*vor* send_cfp&quot;; $self->$code( @params ); print &quot;*nach* send_cfp&quot;; } ;
Moose – Methoden ,[object Object],sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); } } around send_cfp  =>  sub { my ($self,$code,@param) = @_; print &quot;*vor* send_cfp&quot;; $self->$code( @params ); print &quot;*nach* send_cfp&quot;; } ;
Moose – Methoden ,[object Object]
override & super
Moose – Vererbung ,[object Object],package Person; use Moose; has name => (  is => 'ro', isa => 'Str', ); no Moose; 1; package Attendee; use Moose; extends 'Person'; has nr_attended => ( is  => 'ro', isa => 'Int', ); no Moose; 1;
Moose – Vererbung use Attendee; my $person = Attendee->new( name  => 'renee', nr_attended => 3, ); print $person->name,  ': ',  $person->nr_attended;
Moose - Rollen ,[object Object]
Kann zu Problemen bei mehreren Klassen, die die gleiche Subroutine zur Verfügung stellen, führen
-> Rollen
Moose – Rollen
Moose – Rollen
Moose – Rollen

Froscamp2010_moose

  • 1.  
  • 3. Renée Bäcker $foo – Perl-Magazin Frankfurt.pm Selbständiger Perl-Programmierer
  • 4. Moose A postmodern object system for Perl 5
  • 5.  
  • 6.
  • 7. Objektorientierung ist also nichts „natives“ in Perl
  • 8. Dadurch ist vieles nicht so schön wie in anderen Sprachen
  • 9. … vieles muss händisch gemacht werden
  • 10. Warum Moose? package Employee; sub new { bless {} } for my $attr (qw(name title)) { no strict; *$attr = sub { my $self = shift; $self->{ $attr } = shift if @_; return $self->{ $attr }; }; }
  • 11. Warum Moose? package Employee; sub new { bless {} } sub name { my $self = shift; $self->{name} = shift if @_; return $self->{name}; } sub title { my $self = shift; $self->{title} = shift if @_; return $self->{title}; }
  • 12. Warum Moose? class Employee attr_accessor :name attr_accessor :title end
  • 13. Warum Moose? package Employee; use Moose; has name => (is => 'ro'); has title => (is => 'rw');
  • 14.
  • 15. Führt zu wartbarem, lesbarem Perl-Code
  • 17. Elch vs. Kamel – ein Vergleich
  • 19.
  • 21.
  • 22.
  • 23. Moose - Attribute package Event; use Moose; has 'name' => ( is => 'ro' ); no Moose; 1;
  • 24. Moose - Attribute package Event; use Moose; has 'name' => ( is => 'ro' ); no Moose; 1; use Event; my $event = Event->new( name => 'FrOSCamp', ); print $event->name;
  • 25.
  • 26.
  • 27. Moose - Attribute has name => ( is => 'ro', required => 1, ); has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, );
  • 28. Moose - Attribute has name => ( is => 'ro', required => 1, ); has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Man muss einen Namen beim Objekterzeugen angeben!
  • 29. Moose - Attribute has name => ( is => 'ro', required => 1, ); has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Hierfür gibt es sowohl „getter“ als auch „setter“
  • 30. Moose - Attribute has name => ( is => 'ro', required => 1, ); has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Das Attribut ist eine Arrayreferenz, in der nur Strings vorkommen dürfen.
  • 31. Moose - Attribute has name => ( is => 'ro', required => 1, ); has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] }, ); Falls bei der Erzeugung des Objekts keine orga angegeben wird, ist das der Standardwert
  • 32.
  • 34.
  • 35.
  • 36. Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str' => where { length $_[0] <= 140 }; has twitter => ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1, );
  • 37. Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str' => where { length $_[0] <= 140 }; has twitter => ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1, ); Ein neuer Datentyp mit Namen „TwitterMsg“
  • 38. Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str' => where { length $_[0] <= 140 }; has twitter => ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1,, ); … mit „Str“ als Basis
  • 39. Moose – Typen use Moose::Util::TypeConstraints; subtype 'TwitterMsg' => as 'Str' => where { length $_[0] <= 140 } ; has twitter => ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1, ); … und der Bedingung, dass der String kürzer als 140 Zeichen oder genau 140 Zeichen lang ist
  • 40. Moose – Typen $event->twitter( [ 'hallo', 'welt' ], ); print &quot;<<$_>>&quot; for $event->twitter;
  • 41. Moose – Typen $event->twitter( [ 'hallo', 'welt', 'y' x 144 ], ); print &quot;<<$_>>&quot; for $event->twitter; Attribute (twitter) does not pass the type constraint because: Validation failed for 'ArrayRef[TwitterMsg]'
  • 42. Moose – Typen my $event = Event->new( name => 'FrOSCamp', start_date => '17.09.2010', );
  • 43. Moose – Typen subtype 'DateTime' => as 'Object' => where { $_[0]->isa( 'DateTime' ) }; coerce 'DateTime' => from 'Str' => via { my %info; @info{qw/day month year/} = split //, $_; DateTime->new( %info ); }; has start_date => ( is => 'rw', isa => 'DateTime', coerce => 1, );
  • 44.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52. Man bekommt bei „before“ aber die Parameter übergeben
  • 53.
  • 54.
  • 55.
  • 57.
  • 58. Moose – Vererbung use Attendee; my $person = Attendee->new( name => 'renee', nr_attended => 3, ); print $person->name, ': ', $person->nr_attended;
  • 59.
  • 60. Kann zu Problemen bei mehreren Klassen, die die gleiche Subroutine zur Verfügung stellen, führen
  • 66. Moose – Rollen Was, wenn eine Person Speaker und Orga ist?
  • 67. Moose – Rollen Hier besser Rollen verwenden
  • 68.
  • 69. Rollen für kleine wiederverwendbare Verhalten verwenden
  • 70. Ein paar nützliche Rollen gibt es auch schon auf CPAN
  • 71.
  • 72. … oder später eine Rolle für ein Objekt zuweisen
  • 73. Moose – Rollen package OrgaAttendee; use Moose; extends 'Attendee'; with 'Orga'; no Moose; 1;
  • 74. Moose – Rollen package OrgaAttendee; use Moose; extends 'Attendee'; with 'Orga'; no Moose; 1; 'OrgaAttendee' verwendet Rolle 'Orga'
  • 75. Moose – Rollen use OrgaAttendee; my $person = OrgaAttendee->new( name => 'sandro', area => 'everything', ); $person->is_responsible;
  • 76. Moose – Rollen use Attendee; use Speaker; my $person = Attendee->new( name => 'renee' ); Speaker->meta->apply( $person ); $person->speak;
  • 77. Moose – Rollen use Attendee; use Speaker; my $person = Attendee->new( name => 'renee' ); Speaker->meta->apply( $person ); $person->speak; Rolle 'Speaker' wird dem Objekt nachträglich zugeordnet
  • 78.
  • 82. ...
  • 83.
  • 85.
  • 86.
  • 87. Ausgabe 12 – Elchtest (Moose)
  • 88.