Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Introduction to Moose
        Italian Perl Workshop 2009
  Mike Whitaker - BBC / EnlightenedPerl.org
About me
About me

• BBC iPlayer team
About me

• BBC iPlayer team
• ex-Yahoo Europe (News team)
About me

• BBC iPlayer team
• ex-Yahoo Europe (News team)
• ex-CricInfo.com
About me

• BBC iPlayer team
• ex-Yahoo Europe (News team)
• ex-CricInfo.com
• Board member of EnlightenedPerl.org
Why Moose?
Why Moose?


• For that, we need a bit of history:
In the Beginning...
In the Beginning...
• ...there was Perl 5
In the Beginning...
• ...there was Perl 5
• DIY OO
In the Beginning...
• ...there was Perl 5
• DIY OO
•   perldoc perltoot
In the Beginning...
• ...there was Perl 5
• DIY OO
•   perldoc perltoot


      package Foo;

      sub new {
        my $...
In the Beginning...
                              package Foo;

•   ...there was Perl 5       sub new {
                  ...
Perl 5 Native OO
Perl 5 Native OO

• A bit of a hack
Perl 5 Native OO

• A bit of a hack
• Not really a first-class part of the language
Perl 5 Native OO

• A bit of a hack
• Not really a first-class part of the language
• Have to roll your own
So...
People started writing classes to make it
                easier....
Class::Accessor::Classy         Class::Accessor
Object::InsideOut         fields
                                  Hash::Fi...
Moose
What is Moose?
What is Moose?
• (Post)modern Perl OO framework
What is Moose?
• (Post)modern Perl OO framework
• Deals with the overhead of implementing
  OO, allows you to get on with ...
What is Moose?
• (Post)modern Perl OO framework
• Deals with the overhead of implementing
  OO, allows you to get on with ...
What is Moose?
• (Post)modern Perl OO framework
• Deals with the overhead of implementing
  OO, allows you to get on with ...
My First Class
package Person;
use Moose;

has name => (
    is => 'rw',
);

no Moose;
Using the class
use Person;
my $person = Person->new();

$person->name('Mike');

print $person->name();
> Mike
Adding a method
package Person;
use Moose;

has name => ( is => 'rw' );

sub introduce {
    print "I'm " . $self->name;
}
Using it
use Person;
my $person = Person->new();

$person->name('Mike');

$person->introduce();
> I'm Mike
Read-only attributes
package Person;
use Moose;

has name => ( is => 'ro' );

sub introduce {
    print "I'm " . $self->na...
Read-only attributes (2)

use Person;
my $person = Person->new();

$person->name('Mike');
# boom!
Read-only attributes (3)

use Person;
my $person = Person->new(
    { name => 'Mike' },
);

# no boom today!
Changing defaults
has 'name' => (
    isa => 'Str',
    reader => 'get_name',
    writer => 'set_name',
    init_arg => 'n...
Types
package Person;
use Moose;

has name => (
    is => 'rw',
    isa => 'Str',
);
Types (2)
use Person;
my $person = Person->new();

$person->name('Mike');
# shiny!

$person->name( [] );
# boom!
# Not a S...
Types (3)
package Person;
use Moose;

has name => ( is => 'rw', isa => 'Str' );

has dob => (
    is => 'rw',
    isa => '...
Types (4)
use Person;
my $person = Person->new(
   { name => 'Mike' }
);
my $dob = DateTime->new (
   year => 1963, month ...
Subclassing
package Student;
use Moose;
extends qw/Person/;

has overdraft => (
    isa => 'Bool',
    is => 'rw',
);
Compound Types
package Student;
use Moose;
extends qw/Person/;

has classes => (
    isa => 'HashRef[Str]',
    is => 'rw'...
Required attributes
package Student;
use Moose;
extends qw/Person/;
# ...
has course => (
    isa => 'Str',
    is => 'ro'...
Setting defaults
package Student;
use Moose;

has 'overdraft' => (
    isa => 'Bool',
    default => 1,
);
But, what if...

package BankAccount;

sub balance {
    # yadda yadda
}
And then...
package Student;
use Moose;
extends qw/Person/;

has 'account' => (
    isa => 'BankAccount',
    is => 'rw',
...
Lazy default
has 'overdraft' => (
    isa => 'Bool',
    is => 'ro',
    lazy => 1,
    default => sub {
      shift->acco...
Lazy builder
has 'overdraft' => (
    isa => 'Bool',
    is => 'ro',
    lazy_build => 1,
    init_arg => undef,
);
sub _b...
Method modifiers
package Student;
# yadda yadda

after 'introduce' => sub {
    my $self = shift;
    print ', studying ' ....
Using it
use Student;
my $person = Student->new(
    name => 'Mike',
    course => 'Computer Science',
);

$person->introd...
Method modifiers (2)
package Student;
# yadda yadda

around 'introduce' => sub {
    my ($next, $self, @args) = @_;
    pri...
Using around
use Student;
my $person = Student->new(
    name => 'Mike',
    course => 'Computer Science',
);

$person->in...
Roles
Roles
• Code fragments that define and provide a
  small, reusable behaviour
Roles
• Code fragments that define and provide a
  small, reusable behaviour
• Not inherited - methods become part of
  con...
Roles
• Code fragments that define and provide a
  small, reusable behaviour
• Not inherited - methods become part of
  con...
Roles
• Code fragments that define and provide a
  small, reusable behaviour
• Not inherited - methods become part of
  con...
Example role
package Age;
use Moose::Role;
has dob => (
    isa => 'DateTime', is =>'ro'
);
sub age {
    return DateTime-...
Using a role
package Person;
use Moose;
with qw/Age/;
has name => ( isa => 'Str', is => 'ro');

sub introduce {
    print ...
Using a role (2)
use Student;
my $person = Student->new(
    name => 'Mike',
    dob => ... # yadda yadda
    course => 'C...
What we'd really like
use Student;
my $person = Student->new(
    name => 'Mike',
    dob => '05-08-1963',
    course => '...
Redefine our attr...
package Age;
use Moose::Role;
has dob => (
    isa => 'DateStr',
    is =>'ro',
);
Types to the rescue

use Moose::Util::TypeConstraints;

subtype 'DateStr'
    => as 'Str'
    => where {
        /^dd-dd-d...
Types to the rescue (2)
use Moose::Util::TypeConstraints;
class_type 'DateTime';

coerce 'DateTime' => from 'Str'
   => vi...
And then...
package Age;
use Moose::Role;
has dob => (
    isa => 'DateTime',
    is =>'ro',
    coerce => 1, # very impor...
Et voila...
use Student;
my $person = Student->new(
    name => 'Mike',
    dob => '05-08-1963',
    course => 'CS',
);

p...
Roles as interfaces
package Earnings;
use Moose::Role;

requires qw/annual_income/;

sub monthly_income {
    return shift...
Roles as interfaces (2)
package Person;
with qw/Earnings/;

package Student;
extends qw/Person/;

sub annual_income {
   m...
Role gotchas
Role gotchas

• Roles cannot use extends
Role gotchas

• Roles cannot use extends
• requires only works with actual methods :(
Role gotchas

• Roles cannot use extends
• requires only works with actual methods :(
 • for now, at least
Role gotchas

• Roles cannot use extends
• requires only works with actual methods :(
 • for now, at least
• watch out for...
Method Delegation
package Degree;
use Moose;
use Moose::Utils::TypeConstraints;
enum 'Grade' => qw/I IIi IIii III/;


has ...
Method Delegation (2)
package Graduate;
use Moose;
extends qw/Student/;

has 'degree' => (
   isa => 'Degree',
   is => 'r...
Method Delegation (3)
my $g = Graduate->new(name => 'Mike');
my $d = Degree->new(
    awarded => '06-06-1985',
    grade =...
Method Delegation (4)
has 'degree' => (
   isa => 'Degree',
   is => 'rw',
   handles => {
       graduated => 'awarded'
 ...
Method Delegation (5)
my $g = Graduate->new(name => 'Mike');
my $d = Degree->new(
    awarded => '06-06-1985',
    grade =...
More on attributes
package Student;
use MooseX::Util::TypeConstraints;
use Moose;
extends qw/Person/;
enum 'Result' => qw/...
Attribute Helpers
my $st = Student->new( name => 'Mike' );

$st->classes(
    { "Compilers" => 'fail',
     "Numerical Met...
Attribute Helpers (2)
use MooseX::AttributeHelpers;
has classes => (
    metaclass => 'Collection::Hash',
    isa => 'Hash...
Attribute Helpers (3)
my $st = Student->new( name => 'Mike' );

$st->classes(
    { "Compilers" => 'fail',
      "Numerica...
Introspecting Moose
Introspecting Moose
• my $metaclass = $self->meta;
Introspecting Moose
• my $metaclass = $self->meta;
Introspecting Moose
• my $metaclass = $self->meta;

• $metaclass->superclasses;
Introspecting Moose
• my $metaclass = $self->meta;

• $metaclass->superclasses;
• $metaclass->linearized_isa;
Introspecting Moose
• my $metaclass = $self->meta;

• $metaclass->superclasses;
• $metaclass->linearized_isa;
• $metaclass...
Introspecting Moose
• my $metaclass = $self->meta;

• $metaclass->superclasses;
• $metaclass->linearized_isa;
• $metaclass...
Method Signatures
Method Signatures

• We have types...
Method Signatures

• We have types...
• Wouldn't it be nice if types weren't
  restricted to attrs + accessors?
Method Signatures

• We have types...
• Wouldn't it be nice if types weren't
  restricted to attrs + accessors?
• Enter: M...
Method Signatures
package Student;
use Moose;
use MooseX::Method::Signatures;

method attend (Str $class, DateTime
$time) ...
Method Signatures (2)
method attend
  (Str $class, DateTime $time) {
    if (grep $class,
        $self->list_classes) {
 ...
Even more Java-like?
use MooseX::Declare;

class Student extends Person with
Earnings {
   has 'id' => ( isa => 'StudentID...
How is this
implemented?
Lasciate ogne
  speranza,
voi ch'intrate
But seriously...
But seriously...

• Devel::Declare sticks the interpreter on
  pause while it plays with your source
But seriously...

• Devel::Declare sticks the interpreter on
  pause while it plays with your source
• NOT a source filter
But seriously...

• Devel::Declare sticks the interpreter on
  pause while it plays with your source
• NOT a source filter
...
Why Moose?
Why Moose?
• Less code = fewer errors
Why Moose?
• Less code = fewer errors
• Don't waste time on class implementation
Why Moose?
• Less code = fewer errors
• Don't waste time on class implementation
 • Better object model
Why Moose?
• Less code = fewer errors
• Don't waste time on class implementation
 • Better object model
 • "We do this so ...
Why Moose?
• Less code = fewer errors
• Don't waste time on class implementation
 • Better object model
 • "We do this so ...
Why Moose?
• Less code = fewer errors
• Don't waste time on class implementation
 • Better object model
 • "We do this so ...
Further Reading
Further Reading

• http://iinteractive.com/moose/
Further Reading

• http://iinteractive.com/moose/
• Moose::Cookbook (CPAN)
Further Reading

• http://iinteractive.com/moose/
• Moose::Cookbook (CPAN)
• http://www.stonehenge.com/merlyn/
  LinuxMag/...
Complex Example
package Student;
use Moose;

# yadda

has 'id' => (
     isa => 'StudentID',
     is => 'rw',
);
Complex Example (2)
use MooseX::ClassAttribute;

class_has 'db' => (
    isa => 'Str', is => 'rw',
    default => 'dbi:SQL...
Complex Example (3)

sub _build__schema {
    my $self = shift;
    return Person::Schema->connect(
        $self->db
    ...
Complex Example (4)
use Config::General;

override BUILDARGS => sub {
    my $args = super;

     my %conf = Config::Gener...
Complex Example (5)
has _row => {
    isa => 'DBIx::Class::Row',
    lazy_build => 1,
}
sub _build__row {
    return shift...
Complex Example (6)

has _row => {
    isa => 'DBIx::Class::Row',
    lazy_build => 1,
    handles => [qw/address gender/]...
Complex Example (7)
my $student = Student->new(
     name => 'Mike', id => '3056',
);

print $st->address();

# What happe...
What happens?
What happens?
•   address method is handled by _row
What happens?
•   address method is handled by _row

•   _row is lazy_build, so calls _build__row
What happens?
•   address method is handled by _row

•   _row is lazy_build, so calls _build__row

• which requires _schem...
What happens?
•   address method is handled by _row

•   _row is lazy_build, so calls _build__row

• which requires _schem...
What happens?
•   address method is handled by _row

•   _row is lazy_build, so calls _build__row

• which requires _schem...
But...
# What if the student's ID changes?

has 'id' => (
    isa => 'StudentID',
    is => 'rw',
    trigger => '_build__...
Introduction To Moose
Introduction To Moose
Introduction To Moose
Introduction To Moose
Upcoming SlideShare
Loading in …5
×

Introduction To Moose

8,932 views

Published on

Introduction to Moose talk given at Italian Perl Workshop 2009.

Video at http://www.shadowcat.co.uk/archive/conference-video/ipw-2009/moose/

Published in: Technology
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (2019 Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download Full EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download Full doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THIS can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THIS is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBooks .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THIS Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THIS the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THIS Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • -- DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT -- ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... (Unlimited)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • -- DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT -- ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... (Unlimited)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • GIVE HER A BIGGER PACKAGE THIS VALENTINE'S DAY ➤➤ https://tinyurl.com/yy3nfggr
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Acne No More! Cure your acne, end the breakouts and regain your natural inner balance.. Guaranteed! -- Discover how Mike Walden has taught thousands of people to achieve acne freedom faster than they ever thought possible.. Even if you've never succeeded at curing your acne before.. Right here you've found the clear skin success system you've been looking for! ♥♥♥ https://bit.ly/2SaU9sk
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Introduction To Moose

  1. 1. Introduction to Moose Italian Perl Workshop 2009 Mike Whitaker - BBC / EnlightenedPerl.org
  2. 2. About me
  3. 3. About me • BBC iPlayer team
  4. 4. About me • BBC iPlayer team • ex-Yahoo Europe (News team)
  5. 5. About me • BBC iPlayer team • ex-Yahoo Europe (News team) • ex-CricInfo.com
  6. 6. About me • BBC iPlayer team • ex-Yahoo Europe (News team) • ex-CricInfo.com • Board member of EnlightenedPerl.org
  7. 7. Why Moose?
  8. 8. Why Moose? • For that, we need a bit of history:
  9. 9. In the Beginning...
  10. 10. In the Beginning... • ...there was Perl 5
  11. 11. In the Beginning... • ...there was Perl 5 • DIY OO
  12. 12. In the Beginning... • ...there was Perl 5 • DIY OO • perldoc perltoot
  13. 13. In the Beginning... • ...there was Perl 5 • DIY OO • perldoc perltoot package Foo; sub new { my $self = {}; return bless $self; }
  14. 14. In the Beginning... package Foo; • ...there was Perl 5 sub new { my $self = {}; • DIY OO } return bless $self; • perldoc perltoot sub bar { my $self = shift; my $val = shift; package Foo; if (defined $val) { $self->{bar} = $val; sub new { } my $self = {}; else { return bless $self; return $self->{bar}; } } }
  15. 15. Perl 5 Native OO
  16. 16. Perl 5 Native OO • A bit of a hack
  17. 17. Perl 5 Native OO • A bit of a hack • Not really a first-class part of the language
  18. 18. Perl 5 Native OO • A bit of a hack • Not really a first-class part of the language • Have to roll your own
  19. 19. So... People started writing classes to make it easier....
  20. 20. Class::Accessor::Classy Class::Accessor Object::InsideOut fields Hash::FieldHash Badger::Class Rubyish OP Object::Declare Class::Maker UR Class::Gomor Object::Tiny::XS Class::XSAccessor Class::Framework Class::Accessor::Fast Class::Simple Rose::Object MOP::MOP Coat Object::InsideOut Class::STD Class::Object Class::Base Class::ArrayObjects Spiffy Class::Accessor::Grouped Class::Frame Object::Accessor Object::Tiny Object::Simple Class::Generate Class::Builder accessors Fukurama::Class Class::Define Abstract::Meta::Class
  21. 21. Moose
  22. 22. What is Moose?
  23. 23. What is Moose? • (Post)modern Perl OO framework
  24. 24. What is Moose? • (Post)modern Perl OO framework • Deals with the overhead of implementing OO, allows you to get on with coding
  25. 25. What is Moose? • (Post)modern Perl OO framework • Deals with the overhead of implementing OO, allows you to get on with coding • Meta-object implementation - allows you to introspect your classes and objects
  26. 26. What is Moose? • (Post)modern Perl OO framework • Deals with the overhead of implementing OO, allows you to get on with coding • Meta-object implementation - allows you to introspect your classes and objects • Already used in production software
  27. 27. My First Class package Person; use Moose; has name => ( is => 'rw', ); no Moose;
  28. 28. Using the class use Person; my $person = Person->new(); $person->name('Mike'); print $person->name(); > Mike
  29. 29. Adding a method package Person; use Moose; has name => ( is => 'rw' ); sub introduce { print "I'm " . $self->name; }
  30. 30. Using it use Person; my $person = Person->new(); $person->name('Mike'); $person->introduce(); > I'm Mike
  31. 31. Read-only attributes package Person; use Moose; has name => ( is => 'ro' ); sub introduce { print "I'm " . $self->name; }
  32. 32. Read-only attributes (2) use Person; my $person = Person->new(); $person->name('Mike'); # boom!
  33. 33. Read-only attributes (3) use Person; my $person = Person->new( { name => 'Mike' }, ); # no boom today!
  34. 34. Changing defaults has 'name' => ( isa => 'Str', reader => 'get_name', writer => 'set_name', init_arg => 'name', required => 1, );
  35. 35. Types package Person; use Moose; has name => ( is => 'rw', isa => 'Str', );
  36. 36. Types (2) use Person; my $person = Person->new(); $person->name('Mike'); # shiny! $person->name( [] ); # boom! # Not a Str
  37. 37. Types (3) package Person; use Moose; has name => ( is => 'rw', isa => 'Str' ); has dob => ( is => 'rw', isa => 'DateTime', );
  38. 38. Types (4) use Person; my $person = Person->new( { name => 'Mike' } ); my $dob = DateTime->new ( year => 1963, month => 8, day => 5, ); $person->dob($dob); print $person->dob->year; > 1963
  39. 39. Subclassing package Student; use Moose; extends qw/Person/; has overdraft => ( isa => 'Bool', is => 'rw', );
  40. 40. Compound Types package Student; use Moose; extends qw/Person/; has classes => ( isa => 'HashRef[Str]', is => 'rw', );
  41. 41. Required attributes package Student; use Moose; extends qw/Person/; # ... has course => ( isa => 'Str', is => 'ro', required => 1, );
  42. 42. Setting defaults package Student; use Moose; has 'overdraft' => ( isa => 'Bool', default => 1, );
  43. 43. But, what if... package BankAccount; sub balance { # yadda yadda }
  44. 44. And then... package Student; use Moose; extends qw/Person/; has 'account' => ( isa => 'BankAccount', is => 'rw', required => 1, );
  45. 45. Lazy default has 'overdraft' => ( isa => 'Bool', is => 'ro', lazy => 1, default => sub { shift->account->balance < 0; } );
  46. 46. Lazy builder has 'overdraft' => ( isa => 'Bool', is => 'ro', lazy_build => 1, init_arg => undef, ); sub _build_overdraft { return shift->account->balance < 0; }
  47. 47. Method modifiers package Student; # yadda yadda after 'introduce' => sub { my $self = shift; print ', studying ' . $self->course; }
  48. 48. Using it use Student; my $person = Student->new( name => 'Mike', course => 'Computer Science', ); $person->introduce(); > I'm Mike, studying Computer Science
  49. 49. Method modifiers (2) package Student; # yadda yadda around 'introduce' => sub { my ($next, $self, @args) = @_; print "Hi, "; $self->$next(@args); print ', studying ' . $self->course; }
  50. 50. Using around use Student; my $person = Student->new( name => 'Mike', course => 'Computer Science', ); $person->introduce(); > Hi, I'm Mike, studying Computer Science
  51. 51. Roles
  52. 52. Roles • Code fragments that define and provide a small, reusable behaviour
  53. 53. Roles • Code fragments that define and provide a small, reusable behaviour • Not inherited - methods become part of consuming class
  54. 54. Roles • Code fragments that define and provide a small, reusable behaviour • Not inherited - methods become part of consuming class • can be overriden by comsuming class
  55. 55. Roles • Code fragments that define and provide a small, reusable behaviour • Not inherited - methods become part of consuming class • can be overriden by comsuming class • like MI but better!
  56. 56. Example role package Age; use Moose::Role; has dob => ( isa => 'DateTime', is =>'ro' ); sub age { return DateTime->now ->subtract( shift->dob() ) ->years; }
  57. 57. Using a role package Person; use Moose; with qw/Age/; has name => ( isa => 'Str', is => 'ro'); sub introduce { print "I'm " . $self->name . ', age ' . $self->age; }
  58. 58. Using a role (2) use Student; my $person = Student->new( name => 'Mike', dob => ... # yadda yadda course => 'CS', ); $person->introduce(); > Hi, I'm Mike, age 45, studying CS
  59. 59. What we'd really like use Student; my $person = Student->new( name => 'Mike', dob => '05-08-1963', course => 'CS', );
  60. 60. Redefine our attr... package Age; use Moose::Role; has dob => ( isa => 'DateStr', is =>'ro', );
  61. 61. Types to the rescue use Moose::Util::TypeConstraints; subtype 'DateStr' => as 'Str' => where { /^dd-dd-dddd$/ };
  62. 62. Types to the rescue (2) use Moose::Util::TypeConstraints; class_type 'DateTime'; coerce 'DateTime' => from 'Str' => via { my ($d, $m, $y) = split /-/, $_; return DateTime->new( year => $y, month => $m, day => $d ); };
  63. 63. And then... package Age; use Moose::Role; has dob => ( isa => 'DateTime', is =>'ro', coerce => 1, # very important! );
  64. 64. Et voila... use Student; my $person = Student->new( name => 'Mike', dob => '05-08-1963', course => 'CS', ); print $person->age(); > 45
  65. 65. Roles as interfaces package Earnings; use Moose::Role; requires qw/annual_income/; sub monthly_income { return shift->annual_income / 12; }
  66. 66. Roles as interfaces (2) package Person; with qw/Earnings/; package Student; extends qw/Person/; sub annual_income { my $self = shift; return $self->grant_amount; }
  67. 67. Role gotchas
  68. 68. Role gotchas • Roles cannot use extends
  69. 69. Role gotchas • Roles cannot use extends • requires only works with actual methods :(
  70. 70. Role gotchas • Roles cannot use extends • requires only works with actual methods :( • for now, at least
  71. 71. Role gotchas • Roles cannot use extends • requires only works with actual methods :( • for now, at least • watch out for method and attribute conflicts
  72. 72. Method Delegation package Degree; use Moose; use Moose::Utils::TypeConstraints; enum 'Grade' => qw/I IIi IIii III/; has 'grade' => ( isa => 'Grade' ); has 'awarded' => ( isa => 'DateTime', coerce => 1, );
  73. 73. Method Delegation (2) package Graduate; use Moose; extends qw/Student/; has 'degree' => ( isa => 'Degree', is => 'rw', );
  74. 74. Method Delegation (3) my $g = Graduate->new(name => 'Mike'); my $d = Degree->new( awarded => '06-06-1985', grade => 'IIii', ); $g->degree($d); print $g->degree->awarded->year; > 1985
  75. 75. Method Delegation (4) has 'degree' => ( isa => 'Degree', is => 'rw', handles => { graduated => 'awarded' }, );
  76. 76. Method Delegation (5) my $g = Graduate->new(name => 'Mike'); my $d = Degree->new( awarded => '06-06-1985', grade => 'IIii', ); $g->degree($d); print $g->graduated->year; > 1985
  77. 77. More on attributes package Student; use MooseX::Util::TypeConstraints; use Moose; extends qw/Person/; enum 'Result' => qw/pass fail/; has classes => ( isa => 'HashRef[Result]', is => 'rw', predicate => 'has_classes', );
  78. 78. Attribute Helpers my $st = Student->new( name => 'Mike' ); $st->classes( { "Compilers" => 'fail', "Numerical Methods" => 'pass' } ); %{$st->classes}->{"Lisp"} = "pass";
  79. 79. Attribute Helpers (2) use MooseX::AttributeHelpers; has classes => ( metaclass => 'Collection::Hash', isa => 'HashRef[Result]', is => 'rw', provides => { set => 'add_class', keys => 'list_classes', } )
  80. 80. Attribute Helpers (3) my $st = Student->new( name => 'Mike' ); $st->classes( { "Compilers" => 'fail', "Numerical Methods" => 'pass' } ); $st->add_class("Lisp" => 'pass'); print join ", ", $st->list_classes(); > Compilers, Numerical Methods, Lisp
  81. 81. Introspecting Moose
  82. 82. Introspecting Moose • my $metaclass = $self->meta;
  83. 83. Introspecting Moose • my $metaclass = $self->meta;
  84. 84. Introspecting Moose • my $metaclass = $self->meta; • $metaclass->superclasses;
  85. 85. Introspecting Moose • my $metaclass = $self->meta; • $metaclass->superclasses; • $metaclass->linearized_isa;
  86. 86. Introspecting Moose • my $metaclass = $self->meta; • $metaclass->superclasses; • $metaclass->linearized_isa; • $metaclass->has_method("foo");
  87. 87. Introspecting Moose • my $metaclass = $self->meta; • $metaclass->superclasses; • $metaclass->linearized_isa; • $metaclass->has_method("foo"); • $metaclass->get_all_attributes;
  88. 88. Method Signatures
  89. 89. Method Signatures • We have types...
  90. 90. Method Signatures • We have types... • Wouldn't it be nice if types weren't restricted to attrs + accessors?
  91. 91. Method Signatures • We have types... • Wouldn't it be nice if types weren't restricted to attrs + accessors? • Enter: MooseX::Method::Signature
  92. 92. Method Signatures package Student; use Moose; use MooseX::Method::Signatures; method attend (Str $class, DateTime $time) { # ... }
  93. 93. Method Signatures (2) method attend (Str $class, DateTime $time) { if (grep $class, $self->list_classes) { $self->schedule($time, $class); } }
  94. 94. Even more Java-like? use MooseX::Declare; class Student extends Person with Earnings { has 'id' => ( isa => 'StudentID' ); method attend ( Str $class, ... ) { # yadda yadda } }
  95. 95. How is this implemented?
  96. 96. Lasciate ogne speranza, voi ch'intrate
  97. 97. But seriously...
  98. 98. But seriously... • Devel::Declare sticks the interpreter on pause while it plays with your source
  99. 99. But seriously... • Devel::Declare sticks the interpreter on pause while it plays with your source • NOT a source filter
  100. 100. But seriously... • Devel::Declare sticks the interpreter on pause while it plays with your source • NOT a source filter • You don't need to know what's going on...
  101. 101. Why Moose?
  102. 102. Why Moose? • Less code = fewer errors
  103. 103. Why Moose? • Less code = fewer errors • Don't waste time on class implementation
  104. 104. Why Moose? • Less code = fewer errors • Don't waste time on class implementation • Better object model
  105. 105. Why Moose? • Less code = fewer errors • Don't waste time on class implementation • Better object model • "We do this so you don't have to"
  106. 106. Why Moose? • Less code = fewer errors • Don't waste time on class implementation • Better object model • "We do this so you don't have to" • Less need for low level tests
  107. 107. Why Moose? • Less code = fewer errors • Don't waste time on class implementation • Better object model • "We do this so you don't have to" • Less need for low level tests • More descriptive code
  108. 108. Further Reading
  109. 109. Further Reading • http://iinteractive.com/moose/
  110. 110. Further Reading • http://iinteractive.com/moose/ • Moose::Cookbook (CPAN)
  111. 111. Further Reading • http://iinteractive.com/moose/ • Moose::Cookbook (CPAN) • http://www.stonehenge.com/merlyn/ LinuxMag/col94.html
  112. 112. Complex Example package Student; use Moose; # yadda has 'id' => ( isa => 'StudentID', is => 'rw', );
  113. 113. Complex Example (2) use MooseX::ClassAttribute; class_has 'db' => ( isa => 'Str', is => 'rw', default => 'dbi:SQLite:dbname=s.db' ); class_has _schema => ( isa => 'Person::Schema', lazy_build => 1, is => 'ro', );
  114. 114. Complex Example (3) sub _build__schema { my $self = shift; return Person::Schema->connect( $self->db ); }
  115. 115. Complex Example (4) use Config::General; override BUILDARGS => sub { my $args = super; my %conf = Config::General ->new( 'db.conf' )->getall(); $args->{db} = $conf{db} if exists $conf{db}; };
  116. 116. Complex Example (5) has _row => { isa => 'DBIx::Class::Row', lazy_build => 1, } sub _build__row { return shift->_schema ->resultset('Student') ->find($self->id); }
  117. 117. Complex Example (6) has _row => { isa => 'DBIx::Class::Row', lazy_build => 1, handles => [qw/address gender/], }
  118. 118. Complex Example (7) my $student = Student->new( name => 'Mike', id => '3056', ); print $st->address(); # What happens here?
  119. 119. What happens?
  120. 120. What happens? • address method is handled by _row
  121. 121. What happens? • address method is handled by _row • _row is lazy_build, so calls _build__row
  122. 122. What happens? • address method is handled by _row • _row is lazy_build, so calls _build__row • which requires _schema, ALSO lazy_build
  123. 123. What happens? • address method is handled by _row • _row is lazy_build, so calls _build__row • which requires _schema, ALSO lazy_build • which uses id to find the right row in db
  124. 124. What happens? • address method is handled by _row • _row is lazy_build, so calls _build__row • which requires _schema, ALSO lazy_build • which uses id to find the right row in db • Tadaa!
  125. 125. But... # What if the student's ID changes? has 'id' => ( isa => 'StudentID', is => 'rw', trigger => '_build__row', );

×