Froscamp2010_moose
-
Upload
renee-baecker -
Category
Documents
-
view
1.777 -
download
0
Transcript of Froscamp2010_moose
Moose
Rene Bcker
$foo Perl-MagazinFrankfurt.pm
Selbstndiger Perl-Programmierer
MooseA postmodern object system for Perl 5
Warum Moose?
Vor Perl 5 gab es gar keine Objektorientierung in Perl
Objektorientierung ist also nichts natives in Perl
Dadurch ist vieles nicht so schn wie in anderen Sprachen
vieles muss hndisch 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 :titleend
Warum Moose?
package Employee;use Moose;
has name => (is => 'ro');has title => (is => 'rw');
Warum Moose?
Moose vereinfacht diese Dinge enorm
Fhrt zu wartbarem, lesbarem Perl-Code
Ein Vergleich...
Elch vs. Kamel ein Vergleich
MooseEine Einfhrung
Moose Eine Einfhrung
use Moose; use strict;
use warnings;
@ISA = qw(Moose::Object) unless @ISA;Liefert auch new
einige neue Schlsselwrter
Moose - Attribute
has ist Schlsselwort fr Attribute
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
Eigenschaftenis =>'ro' read only
'rw' read/write
isa =>Von welchem Datentyp ist das Attribut
default => Standardwert des Attributs
required => Muss es angegeben werden?
...
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 beimObjekterzeugen angeben!
Moose - Attribute
has name => ( is => 'ro', required => 1,);
has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] },);
Hierfr gibt es sowohl getterals 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 vorkommendrfen.
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 Objektskeine orga angegeben wird,ist das der Standardwert
Moose - Typen
has orga => ( is => 'rw', isa => 'ArrayRef[Str]', default => sub{ [qw/Sandro Marcus/] },);
Moose hat einige Builtin-Typen
Moose Typen
Moose Typen
aber man kann auch eigene Typen erstellen, fr vieles reicht es, den Klassennamen anzugeben
has start_date => ( is => 'rw', isa => 'DateTime',);
Moose Typen
aber man kann auch eigene Typen erstellen, fr vieles reicht es, den Klassennamen anzugeben
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] ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1,);
Moose Typen
use Moose::Util::TypeConstraints;
subtype 'TwitterMsg' => as 'Str' => where { length $_[0] ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1,);
Ein neuer Datentyp mitNamen TwitterMsg
Moose Typen
use Moose::Util::TypeConstraints;
subtype 'TwitterMsg' => as 'Str' => where { length $_[0] ( 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] ( is => 'rw', isa => 'ArrayRef[TwitterMsg]', auto_deref => 1,);
und der Bedingung,dass der String krzer als 140Zeichen oder genau 140 Zeichenlang ist
Moose Typen
$event->twitter( [ 'hallo', 'welt' ],);
print "\n" for $event->twitter;
Moose Typen
$event->twitter( [ 'hallo', 'welt', 'y' x 144 ],);
print "\n" 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
Man kann noch mehr mit den Attributen machen:Zustzliche Methoden delegieren
In Subklassen zustzlich erweitern
Moose - Methoden
Erstmal nichts besonderes wie bei Standard Perl 5 OO
sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); }}
Moose Methoden
aber man kann tolle Sachen drumherum machenCode vor der der Subroutine aufrufen
sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); }}
before send_cfp => sub { print "*vor* send_cfp\n";};
Moose Methoden
aber man kann tolle Sachen drumherum machenCode vor der der Subroutine aufrufen
sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); }}
before send_cfp => sub { print "*vor* send_cfp\n";};
Moose Methoden
Code nach der Subroutine ausfhren
sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); }}
after send_cfp => sub { print "*nach* send_cfp\n";};
Moose Methoden
Code nach der Subroutine ausfhren
sub send_cfp { my ($self,@recipients) = @_; for my $recipient ( @recipients ) { $self->send_email( $recipient, $self->cfp ); }}
after send_cfp => sub { print "*nach* send_cfp\n";};
Moose Methoden
Bei before und after hat man allerdings keinen Einfluss auf Parameter fr die Originalmethode oder deren Rckgabewert
Man bekommt bei before aber die Parameter bergeben
Moose Methoden
Code drumherum ausfhren
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 "*vor* send_cfp\n"; $self->$code( @params ); print "*nach* send_cfp\n";};
Moose Methoden
Code drumherum ausfhren
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 "*vor* send_cfp\n"; $self->$code( @params ); print "*nach* send_cfp\n";};
Moose Methoden
Noch mehr mglichaugment & inner
override & super
Moose Vererbung
Vererbung mit Schlsselwort 'extends'
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
Moose untersttzt MehrfachvererbungAber wer will das?
Kann zu Problemen bei mehreren Klassen, die die gleiche Subroutine zur Verfgung stellen, fhren
Rollen
Moose Rollen
PersonAttendee
Moose Rollen
PersonAttendee
Speaker
Moose Rollen
PersonAttendee
Orga
Moose Rollen
PersonAttendee
Orga
Speaker
Moose Rollen
PersonAttendee
Orga
Speaker
Was, wenn eine Person Speaker und Orga ist?
Moose Rollen
PersonAttendee
Hier besser Rollen verwenden
SpeakerOrga
Moose Rollen
Rollen definieren ein VerhaltenSind wie Java Interfaces (safe) und mixins (useful)
Rollen fr kleine wiederverwendbare Verhalten verwenden
Ein paar ntzliche Rollen gibt es auch schon auf CPAN
Moose Rollen
Entweder direkt einer Klasse zuweisen
oder spter eine Rolle fr ein Objekt zuweisen
Moose Rollen
package OrgaAttendee;
use Moose;
extends 'Attendee';with 'Orga';
no Moose;
1;
Moose Rollen
package OrgaAttendee;
use Moose;
extends 'Attendee';with 'Orga';
no Moose;
1;
'OrgaAttendee' verwendet Rolle 'Orga'
Moose Rollen
use OrgaAttendee;
my $person = OrgaAttendee->new( name => 'sandro', area => 'everything',);
$person->is_responsible;
Moose Rollen
use Attendee;use Speaker;
my $person = Attendee->new( name => 'renee' );
Speaker->meta->apply( $person );$person->speak;
Moose Rollen
use Attendee;use Speaker;
my $person = Attendee->new( name => 'renee' );
Speaker->meta->apply( $person );$person->speak;
Rolle 'Speaker' wird demObjekt nachtrglichzugeordnet
Moose - Erweiterungen
Etliche Module im MooseX::*-NamensraumMooseX::Types (::UUID, ::URI, ::NetAddr::IP, ::XMLSchema)
MooseX::Role::Parameterized
MooseX::Singleton
MooseX::Declare
...
Moose ein Fazit
Weniger Code bei Verwendung von MooseWeniger Fehleranfllig
Bessere Wartbarkeit
Bessere Lesbarkeit
Die Hauptarbeit wird dem Programmierer abgenommen
Moose - Lesestoff
Moose::Cookbookhttp://search.cpan.org/dist/Moose/...
$foo Perl-MagazinAusgabe 4 Moose
Ausgabe 12 Elchtest (Moose)
Ab Ausgabe 15 Moose-Tutorial
Moose-Webseitehttp://moose.perl.org