SlideShare uma empresa Scribd logo
1 de 78
(Parameterized)
     Roles
    Shawn M Moore
 Best Practical Solutions

    http://sartak.org
"The more I use roles, the less I
 understand why anyone would
  want to use the inheritance
        model." - Ovid
"A role-aware type system allows
  you to express yourself with
        better genericity."
           - chromatic
"Roles are the sound of diamond
  inheritance that people have
  stopped banging their heads
         against." - hdp
                      (    )
Example Role
package Counter;
use Moose::Role;

has counter => (
   is   => 'ro',
   isa   => 'Int',
   default => 0,
);

sub increment {
  my $self = shift;
  $self->counter($self->counter + 1);
}
Example Role
package Counter;
use Moose::Role;

has counter => (
   is   => 'ro',
   isa   => 'Int',
   default => 0,
);

sub increment {
  my $self = shift;
  $self->counter($self->counter + 1);
}

           use                          Moose
Example Role
use MooseX::Declare;

role Counter {
   has counter => (
      is   => 'ro',
      isa   => 'Int',
      default => 0,
   );

    method increment {
      $self->counter($self->counter + 1);
    }
}
Consuming a Role

class Odometer with Counter {
   method reset(Crook $you) {
     $you->break_into($self);
     $self->counter(0);
     $you->plead('innocent');
   }
}



                   with
Odometer Fraud


http://en.wikipedia.org/wiki/Odometer_fraud
Consuming a Role

class Odometer with Counter {
   method reset(Crook $you) {
     $you->break_into($self);
      $self->counter(0);
     $you->plead('innocent');
   }
}


                                counter
Consuming a Role

class Odometer extends Widget with Counter {
   method reset(Crook $you) {
     $you->break_into($self);
     $self->counter(0);
     $you->plead('innocent');
   }
}
class Odometer extends Widget {
   has counter => (
      is   => 'ro',
      isa   => 'Int',
      default => 0,
   );

    method increment {
      $self->counter($self->counter + 1);
    }

    method reset(Crook $you) {
      $you->break_into($self);
      $self->counter(0);
      $you->plead('innocent');
    }
}
Class Building
              Blocks
class Action::Throw
  with Action::Role::Direction
  with Action::Role::Item {
   …
}

class Action::Melee
  with Action::Role::Monster
  with Action::Role::Direction {
   …
}
Class Building
              Blocks
class Action::Throw
  with Action::Role::Direction
  with Action::Role::Item {
   …
}

class Action::Melee
  with Action::Role::Monster
  with Action::Role::Direction {
   …
}
Class Building
             Blocks
class Action::Throw
  extends Action::Direction
  extends Action::Item {
   …
}

class Action::Melee
  extends Action::Monster
  extends Action::Direction {
   …
}
Multiple Inheritance
class Action::Monster {
   has monster => (…);
   method name {
     $self->monster->name
   }
}
Multiple Inheritance

class Action::Direction {
   has direction => (…);
}




                     direction
Multiple Inheritance

class Action::Melee
extends Action::Direction
extends Action::Monster {
   …
}




                            …
Multiple Inheritance
class Action::Direction {
   has direction => (…);
   method name {
     $self->direction->name
   }
}




        name
Multiple Inheritance


 $melee->name


     name
Multiple Roles

class Action::Melee
with Action::Direction
with Action::Monster {
  …
}
Multiple Roles

Due to a method name conflict in roles
'Action::Direction' and 'Action::Monster', the
method 'name' must be implemented or
excluded by 'Action::Melee'




  Moose
AT
COMPILE
 TIME!
     !
Conflict Resolution

class Action::Melee
with Action::Direction
with Action::Monster {
   …
}
Conflict Resolution

class Action::Melee
with Action::Direction
with Action::Monster {
   method name { "melee" }
}
Conflict Resolution

class Action::Melee
with Action::Direction
with Action::Monster excludes name
{…}
class Action::Melee
with Action::Direction
alias { name => 'direction_name' }
with Action::Monster
alias { name => 'monster_name' }
{
   method name {
      loc '%1 (at %2)',
         $self->monster_name,
         $self->direction_name;
   }
}
 2
Conflict Resolution

Due to a method name conflict in roles
'Action::Direction' and 'Action::Monster', the
method 'name' must be implemented or
excluded by 'Action::Melee'
Conflict Resolution

Due to a method name conflict in roles
'Action::Direction' and 'Action::Monster', the
method 'name' must be implemented or
excluded by 'Action::Melee'
Conflict Resolution

Due to a method name conflict in roles
'Action::Direction' and 'Action::Monster', the
method 'name' must be implemented or
excluded by 'Action::Melee'
Conflict Resolution

class Action::Melee
extends Action::Direction
extends Action::Monster
   excludes name
{…}
"Roles are the
 sound of diamond
   inheritance that
     people have
  stopped banging
their heads against."
        - hdp
Required Methods

role Action::Role::Monster {
   method monster {
     $self->tile->monster
   }

    method has_monster {
      $self->tile->has_monster
    }
}
Required Methods


class Action::Chat
with Action::Role::Monster {
   method run { print "woof" }
}
Required Methods



$chat->has_monster
Required Methods



   Can't locate object method "tile" via package
   "Action::Chat"




tile
Required Methods
role Action::Role::Monster {
   requires 'tile';

    method monster {
      $self->tile->monster
    }

    method has_monster {
      $self->tile->has_monster
    }
}
Required Methods



'Action::Role::Monster' requires the method
'tile' to be implemented by 'Action::Chat'
Default
      Implementation
role Scan {
   requires 'entries';

    method ages {
      map { $_->age }
        $self->entries
    }
}
Default
     Implementation

class Backend::Hash with Scan {
   method entries {
     values %{ $self->storage }
   }
}
Default
        Implementation
class Backend::DBI with Scan {
   method entries {
     $self->q("SELECT * …");
   }

    method ages {
      $self->q("SELECT age …");
    }
}
Default
        Implementation
class Backend::DBI with Scan {
   method entries {
     $self->q("SELECT * …");
   }

    method ages {
      $self->q("SELECT age …");
    }
}
Default
        Implementation
class Backend::DBI with Scan {
   method entries {
     $self->q("SELECT * …");
   }

    method ages {
      $self->q("SELECT age …");
    }
}
                Scan
"The more I use
  roles, the less I
  understand why
anyone would want
     to use the
inheritance model."
       - Ovid
Allomorphism


 Role = Type
Allomorphism


Role = Semantics
Allomorphism

Role = Type

Role = Semantics
Allomorphism


role Interface::Nonblocking {
   requires 'read', 'write';
}



                       read     write
Allomorphism


class Nonblocking::Socket
with Interface::Nonblocking {
   method read { … }
   method write { … }
}
Allomorphism


class Blocking::Socket {
   method read { … }
   method write { … }
}
Allomorphism

my $s = shift;

$s->does('Interface::Nonblocking')
  or confess 'No blocking!';

$s->write('          ');
Duck Typing

my $s = shift;

$s->can('read') && $s->can('write')
  or confess 'Need an interface';

$s->write('          ');
Allomorphism

my $s = shift;

$s->does('Interface::Nonblocking')
  or confess 'No blocking!';

$s->write('          ');

      write
Allomorphism


has connection => (
  isa => 'Nonblocking::Socket',
);
Allomorphism


has connection => (
  isa => 'Nonblocking::Socket',
  does => 'Interface::Nonblocking',
);
"A role-aware type
 system allows you
to express yourself
     with better
    genericity."
    - chromatic
Extensions

class WWW::Mechanize::TreeBuilder
extends WWW::Mechanize {
   has tree => (
      …
   );
   around _make_request {
      …
   }
}
Extensions

class Test::WWW::Mech::TreeBuilder
extends Test::WWW::Mechanize {
   has tree => (
      …
   );
   around _make_request {
      …
   }
}
Extensions

class WWW::Mech::Cache::TreeBuilder
extends WWW::Mechanize::Cached {
   has tree => (
      …
   );
   around _make_request {
      …
   }
}

      Mech
Extensions



BAD!
Extensions

role WWW::Mechanize::TreeBuilder {
   has tree => (
      …
   );
   around _make_request {
      …
   }
}
Extensions


class Test::WWW::Mech::TreeBuilder
extends Test::WWW::Mechanize
with WWW::Mechanize::TreeBuilder {}
Extensions


class WWW::Mech::Cache::TreeBuilder
extends WWW::Mechanize::Cached
with WWW::Mechanize::TreeBuilder {}
Extensions


Roles >
Inheritance
Role -> Object
role Rootey {
   method su { … }
}

$jrock = User->new("jrockway");
$shawn = User->new("sartak");

Rootey->meta->apply($shawn);

$shawn->su; # ok
$jrock->su; # dies!
Plugins

MooseX::Object::Pluggable

     MooseX::Traits
Classes are Nouns
     Message
       User
      Service
     Request
     Response
Methods are Verbs
    send_message
      add_user
  connect_to_service
   handle_request
   serve_response
Roles are Adjectives
      HasPlugins
    RequiresPlugins
      Throwable
      Reblessing
  ExtendsObject::User
Parameterized Roles
role Scan {
   requires 'entries';

    method ages {
      map { $_->age }
        $self->entries
    }
}
Parameterized Roles


 MooseX::Role::Parameterized




                 Moose
Parameterized Roles
role Counter (Int :$default = 0) {
   has counter => (
      is   => 'ro',
      isa   => 'Int',
      default => $default,
   );

    sub increment {
      my $self = shift;
      $self->counter($self->counter + 1);
    }
}
Parameterized Roles


class Odometer
  with Counter(default => 10000) {
   …
}




                             66
Parameterized Roles

role Speedometer (Str :$method) {
   around $method {
      my $start = time;
      $orig->(@_);
      print "$method " . (time - $start);
   }
}




                                66
Parameterized Roles
role WWW::Search (Str :$engine) {
   method search (Str $query) {
     if ($engine eq "Google") {
         REST::Google::Search->…
     } elsif ($engine eq "Yahoo!") {
         Yahoo::Search->…
     } elsif ($engine eq "Bing") {
         die "seriously?";
     }

        # post-process @results
    }
}

                                  66
Parameterized Roles
package Valid::Adding;
use MooseX::Role::Parameterized;

role {
   $consumer->does('Adding') or die;
   $consumer->add(2, 6) == 8 or die;

     method safe_add => sub {
        …
     };
};


                                66
Roles
Class building blocks
Conflicts, resolution
 Required methods
Allomorphism (types)
Extensions, Plugins
    "adjectives"
Thanks to my
  Vlad Dogsby
  Thomas Figg
Alexander Hoffer
  Stevan Little
  Lucas Oman
 Simon Pollard
Thanks to my



Kenichi Ishigaki
   charsbar++
See Also
           Moose::Manual::Roles


          "The Why of Perl Roles"


"Eliminating Inheritance via Smalltalk-Style
                  Traits"


"Traits - Composing Classes from Behavioral
             Building Blocks"

Mais conteúdo relacionado

Mais procurados

5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScriptTodd Anglin
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with MooseDave Cross
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev AssistantDave Cross
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 
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
 
PHP Functions & Arrays
PHP Functions & ArraysPHP Functions & Arrays
PHP Functions & ArraysHenry Osborne
 
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
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developersAndrew Eddie
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010leo lapworth
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.boyney123
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 

Mais procurados (20)

5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Improving Dev Assistant
Improving Dev AssistantImproving Dev Assistant
Improving Dev Assistant
 
Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
 
Syntax
SyntaxSyntax
Syntax
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
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
 
PHP Functions & Arrays
PHP Functions & ArraysPHP Functions & Arrays
PHP Functions & Arrays
 
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
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
Scala vs Ruby
Scala vs RubyScala vs Ruby
Scala vs Ruby
 
Perl
PerlPerl
Perl
 

Destaque

Moose Design Patterns
Moose Design PatternsMoose Design Patterns
Moose Design PatternsYnon Perek
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6 brian d foy
 
Cool Things in Perl 6
Cool Things in Perl 6Cool Things in Perl 6
Cool Things in Perl 6brian d foy
 
Perl family: 15 years of Perl 6 and Perl 5
Perl family: 15 years of Perl 6 and Perl 5Perl family: 15 years of Perl 6 and Perl 5
Perl family: 15 years of Perl 6 and Perl 5Michal Jurosz
 
Extending Moose
Extending MooseExtending Moose
Extending Moosesartak
 
Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Andrew Shitov
 
Test::Class::Moose
Test::Class::MooseTest::Class::Moose
Test::Class::MooseCurtis Poe
 

Destaque (8)

Moose Design Patterns
Moose Design PatternsMoose Design Patterns
Moose Design Patterns
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6
 
Cool Things in Perl 6
Cool Things in Perl 6Cool Things in Perl 6
Cool Things in Perl 6
 
Perl family: 15 years of Perl 6 and Perl 5
Perl family: 15 years of Perl 6 and Perl 5Perl family: 15 years of Perl 6 and Perl 5
Perl family: 15 years of Perl 6 and Perl 5
 
Extending Moose
Extending MooseExtending Moose
Extending Moose
 
Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6
 
Test::Class::Moose
Test::Class::MooseTest::Class::Moose
Test::Class::Moose
 
TraitとMoose::Role
TraitとMoose::RoleTraitとMoose::Role
TraitとMoose::Role
 

Semelhante a (Parameterized) Roles

Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionIban Martinez
 
JQuery: JavaScript Library of the Future
JQuery: JavaScript Library of the FutureJQuery: JavaScript Library of the Future
JQuery: JavaScript Library of the FutureMatthew Taylor
 
The Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J QueryThe Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J QueryQConLondon2008
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First WidgetChris Wilcoxson
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Writing JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptxWriting JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptxEd Charbeneau
 
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
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!Guilherme Carreiro
 
Cheap frontend tricks
Cheap frontend tricksCheap frontend tricks
Cheap frontend tricksambiescent
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Ben Lesh
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Nikita Popov
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPMichael Francis
 
Drush. Secrets come out.
Drush. Secrets come out.Drush. Secrets come out.
Drush. Secrets come out.Alex S
 

Semelhante a (Parameterized) Roles (20)

Javascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introductionJavascript & jQuery: A pragmatic introduction
Javascript & jQuery: A pragmatic introduction
 
JQuery: JavaScript Library of the Future
JQuery: JavaScript Library of the FutureJQuery: JavaScript Library of the Future
JQuery: JavaScript Library of the Future
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
The Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J QueryThe Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J Query
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First Widget
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Writing JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptxWriting JavaScript for C# Blazor.pptx
Writing JavaScript for C# Blazor.pptx
 
Javascript in Plone
Javascript in PloneJavascript in Plone
Javascript in Plone
 
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
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
 
Cheap frontend tricks
Cheap frontend tricksCheap frontend tricks
Cheap frontend tricks
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Web::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTPWeb::Machine - Simpl{e,y} HTTP
Web::Machine - Simpl{e,y} HTTP
 
Drush. Secrets come out.
Drush. Secrets come out.Drush. Secrets come out.
Drush. Secrets come out.
 

Último

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 

Último (20)

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 

(Parameterized) Roles

Notas do Editor

  1. Presented YAPC::Asia, 2009-09-11. Tokyo Institute of Technology, Tokyo, Japan.
  2. You've probably heard a lot about this new feature called "roles" lately. Not only are a lot of people talking about roles, but a lot of people are using roles. And for good reason!
  3. Before I get into what a role is, and why roles are awesome, I want to just dive into what a role looks like.
  4. You might notice a strong resemblance to regular Moose code. The only difference is that we "use Moose::Role" instead of "use Moose". This means that this package represents a role instead of a class. Oh, damnit, wait a second.
  5. Much better. Anyway, so we have a role named Counter with an attribute and an increment method. Roles are not classes, so we can't call Counter->new. A role is more just a container for methods and attributes.
  6. This is what consuming a role looks like. Here we have a class that needs a counter for keeping track of how many miles you have driven. "with" is the key word for consuming a role, much like "extends" is the key word for subclassing.
  7. It is a very serious crime.
  8. As you can see here, the role has added the counter attribute to Odometer. It also gained the increment method, which is presumably called by other parts of the system.
  9. I must stress that consuming a role is not inheritance. You can still use inheritance alongside roles. What roles do are "flatten" its bits into the class.
  10. The flattening is a lot like copying and pasting the code from the role into its consumer. That's even a pretty good description of what happens behind the scenes, though it doesn't happen at the strings-of-code level.
  11. My favorite feature of roles is their reusability. One way to look at roles is that they are class building blocks.
  12. If we factor out common behavior, we get to name that chunk of behavior, and reuse all that code. We know that these two actions have something to do with direction.
  13. You might be wondering how any of this is better than multiple inheritance. Surely you know multiple inheritance is evil, right? RIGHT? By the way, did anyone here even know how to use multiple inheritance with MooseX::Declare? I sure didn't until I wrote this slide.
  14. Let's look at an example of why multiple inheritance is maligned. Here we have a class with a "name" method.
  15. Now we have another class. It just has a direction.
  16. And now we have a class that inherits from both of those. So everything is fine right now. But at some point the requirements change.
  17. We need a "name" method in Action::Direction for some other class.
  18. This used to return monster name. Now this has changed without warning to the direction name, because Action::Direction is the leftmost parent. I hope your tests are very thorough! This is a huge pain to debug. Code reuse and cleanliness is often not worth this pain, so we avoid multiple inheritance.
  19. If these were roles instead, something very different happens.
  20. Once we add the "name" method to Direction, we get this error. I'll talk about what it means soon, but one nice thing about this error is Moose throws it..
  21. ...immediately. You don't have to wait for the class to be instantiated, or the "name" method to be called. Moose throws conflict error at "with" time.
  22. So this code is an error. But as alluded to in the error message, we can resolve this conflict. There are several ways to do this.
  23. The class could define its own method. When a class defines a method and a role it consumes defines the same method, the class wins. So this resolves the conflict by overriding the "name" methods from the two roles. It's kind of like plugging your ears and yelling that everything is okay. But sometimes that really is all you need.
  24. Another option is to exclude one of the conflicting methods. This way, Direction's "name" method is the one that is added to Melee. Obviously you can only use this where it makes sense. It probably doesn't make sense to use it in this example. XXX: This syntax doesn't actually work yet as of 2009-08-22. A failing test has been submitted!
  25. Another option is to combine the two methods. Here we disambiguate the two conflicting "name" methods, then use them in our own "name" method which serves both roles well enough. I've found that this is usually the best solution.
  26. So now we know what this error message means.
  27. You can override the conflicting methods in the class, with or without reusing each conflicting method.
  28. Or, if it makes sense, just exclude one of the methods so that it's no longer a conflict.
  29. Try that with multiple inheritance. Yeah right!
  30. Because of the flattening property of roles, and because of this conflict detection and resolution, the diamond inheritance problem doesn't apply to roles. Any ambiguity is a compile-time error, and the programmer has several tools to resolve such ambiguities. Role composition is much more pleasant to work with than multiple inheritance.
  31. Suppose we have a role that assumes a particular method exists in each of its consumers. In this case, we're calling "tile" even though we don't know for sure that each consumer will have that method.
  32. This code will work fine. We consume the role, Action::Chat gets the new methods, and everything is hunky-dory.
  33. But at runtime when we try to call this method, we get an error.
  34. This sucks. The author of the Monster role demands that consumers have a "tile" method. Perhaps the role's documentation does notify you that consumers must have it, but who even reads documentation any more? It would be nice to be able to codify this requirement.
  35. And, of course, you can. If a role calls methods that it doesn't provide itself, the role should require them.
  36. And like a conflict, we get this error at compile time. Much better than a method-missing error at runtime when we try to call ->tile. The Moose team really likes the fail-fast principle.
  37. Here we have a role that requires an "entries" method, then builds on top of it with another method "ages".
  38. We have an example backend that stores its entries in a hash table. We provide the "entries" method that the Scan role requires. That role gives us an "ages" method that calls "entries". Pretty straightforward use of roles.
  39. When I was describing conflict resolution I mentioned how a method defined by the class wins over a method pulled in from a role. That's useful even outside of conflict resolution.
  40. The ages method we define is doing a lot less work than the default implementation provided by the role would do. We don't need to pull in every field of every entry then pick out the values for age. However, the role's implementation is a good default that would be useful for a lot of these backends. Method overrides permit reuse but allow optimizations or alternate implementations where needed.
  41. You might be asking why we bother to consume Scan even though we don't actually pull in any methods or attributes from it. That's next!
  42. Roles have so many excellent features that I am starting to agree with this (admittedly radical) viewpoint myself.
  43. Allomorphism is a fancy word that means a few things. For one, roles can be part of the type system. It's a lot like duck typing, but more explicit.
  44. Allomorphism also means that a role implies semantics. Basically, every method implemented or required by the role must implement some specified behavior.
  45. These imply similar consequences, so I'm going to explain them together.
  46. Here we have a role that requires "read" and "write" methods from each of its consumers. Given the name of the role, we can guess that the role requires these methods to be nonblocking.
  47. Here we define a class that does the nonblocking interface. Nonblocking::Socket promises that its read and write methods fulfill the socket's nonblocking requirements.
  48. Here's another class, one whose read and write methods do block. Even though it fulfills the method name requirements of Interface::Nonblocking, this class would be lying if it declared that it does the role.
  49. We can ask an object if it does a particular role. This will die if we try to use a Blocking::Socket here. This is better than checking "isa" because we actually care about capability. We don't care what $s's class is, or what its ancestors are. Any class can declare that it does the Interface::Nonblocking role, as long as it fulfills the role's contract.
  50. Duck typing fulfills this same need. We also don't care about what class $s is, as long as it has the methods we want. However, the problem with duck typing is that merely having a set of methods does not imply semantics. Perhaps read and write are actually going to do text-to-speech and printing a term paper. Or worse, they might block.
  51. In any case, because the Interface::Nonblocking role requires the write method, we know that $s will not only have it, but we know it will not block.
  52. Moose has support for allomorphism in attributes. Instead of demanding that connection be a particular class...
  53. … we can demand that the value of connection does a particular role.
  54. chromatic's point here is that you can stop caring about hierarchy and start caring about capabilities. Allomorphism means you don't need to subclass someone's crack-fueled module. You need only fulfill its crack-fueled interface. It's OOP freedom.
  55. Here's a quick tip for you. Say you're extending a module. Ordinarily you'd write a subclass, right?
  56. You write good tests, so you subclass its test subclass too.
  57. You also have to subclass all the other subclasses you use. Maybe it'd be better to just monkeypatch WWW::Mechanize. Who'd know?
  58. No! Don't do it! You'll screw it up for anyone else who happens to use that module in your codebase.
  59. Just make your extension a role.
  60. Now you can apply this role to the existing subclasses of the module. There's no dot-dot-dot in the braces here. This is a full class definition.
  61. That's really it. You don't need any other code. All the extension code is in your role. Nice and clean.
  62. There, I said it! If you can implement your extension as a role, do it. Use inheritance sparingly.
  63. I don't want to spend much time on this, but you can apply a role to a particular object. It doesn't have to be a full-blown class. It also won't affect any other objects. Which is good, because I wouldn't trust Jon with root.
  64. Roles are nice for plugins too. I covered this heavily in my API Design talk. The idea is each plugin is just a role. These two modules make roles-as-plugins very easy. http://sartak.org/talks/yapc-asia-2009/api-design/
  65. To give you an idea of how to think about roles, here's a pretty simple metaphor that works for me. Classes are nouns.
  66. Methods are verbs. They are simple behaviors. They do things.
  67. Roles are adjectives. These are all good role names. If you think of some piece of behavior as an adjective, that's a good sign that it can be factored out as a role.
  68. This is a very specific kind of parameterized role. Each consumer parameterizes the "ages" method by providing an "entries" method. But that's not really what I'm talking about when I say parameterized role. If you can do this, do it. If you need something more advanced...
  69. Parameterized roles are my biggest contribution to Moose. I'm happy with how they came out.
  70. Here we have our old Counter role, but now each consumer can declare what default it wants for the attribute. If they choose nothing, they get the default of 0. rafl++ added parameterized role support to MooseX::Declare recently, so my examples get to look much nicer.
  71. Using a parameterized role is pretty much the same. You just pass in the named arguments to "with". This was an example of parameterizing an attribute, and is probably the most common use of p-roles.
  72. Here we have a role that wraps any method you give it with a bit of profiling code. This is sort of the inverse of "requires". Instead of the role telling you what method you need, you tell the role what method it needs to instrument. Someone once praised this type of p-role usage as resembling macros.
  73. One really nice thing about parameterized roles is that they improve code reuse. All the consumer has to do is inform the role of which search engine they want to use. The role takes care of the rest. This means each consumer writes less code, because the parameterized role can build up more structure.
  74. Here's another use case that was raised recently. The parameterized role could perform additional validation on each consumer. This is like "requires" for method names, but stronger. This is what pre-MooseX::Declare parameterized roles look like, due to language constraints.
  75. Roles are all of these things. I hope I've convinced you to use roles in your next project's design. Thank you!
  76. Thanks to these people who have reviewed my slides and offered excellent advice.
  77. Thank you to Ishigaki-san for translating my slides!
  78. http://search.cpan.org/perldoc?Moose::Manual::Roles http://www.modernperlbooks.com/mt/2009/04/the-why-of-perl-roles.html http://use.perl.org/~Ovid/journal/39404 http://scg.unibe.ch/archive/phd/schaerli-phd.pdf