SlideShare a Scribd company logo
1 of 129
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 $self = {};
        return bless $self;
      }
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};
      }                         }
                              }
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::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
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 coding
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
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
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->name;
}
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 => 'name',
    required => 1,
);
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 Str
Types (3)
package Person;
use Moose;

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

has dob => (
    is => 'rw',
    isa => 'DateTime',
);
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
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',
    required => 1,
);
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',
    required => 1,
);
Lazy default
has 'overdraft' => (
    isa => 'Bool',
    is => 'ro',
    lazy => 1,
    default => sub {
      shift->account->balance < 0;
    }
);
Lazy builder
has 'overdraft' => (
    isa => 'Bool',
    is => 'ro',
    lazy_build => 1,
    init_arg => undef,
);
sub _build_overdraft {
   return shift->account->balance < 0;
}
Method modifiers
package Student;
# yadda yadda

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

$person->introduce();
> I'm Mike, studying Computer Science
Method modifiers (2)
package Student;
# yadda yadda

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

$person->introduce();
> Hi, I'm Mike, studying Computer Science
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
  consuming class
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
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!
Example role
package Age;
use Moose::Role;
has dob => (
    isa => 'DateTime', is =>'ro'
);
sub age {
    return DateTime->now
     ->subtract( shift->dob() )
     ->years;
}
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;
}
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
What we'd really like
use Student;
my $person = Student->new(
    name => 'Mike',
    dob => '05-08-1963',
    course => 'CS',
);
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-dddd$/
    };
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
     );
  };
And then...
package Age;
use Moose::Role;
has dob => (
    isa => 'DateTime',
    is =>'ro',
    coerce => 1, # very important!
);
Et voila...
use Student;
my $person = Student->new(
    name => 'Mike',
    dob => '05-08-1963',
    course => 'CS',
);

print $person->age();
> 45
Roles as interfaces
package Earnings;
use Moose::Role;

requires qw/annual_income/;

sub monthly_income {
    return shift->annual_income / 12;
}
Roles as interfaces (2)
package Person;
with qw/Earnings/;

package Student;
extends qw/Person/;

sub annual_income {
   my $self = shift;
   return $self->grant_amount;
}
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 and attribute
  conflicts
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,
);
Method Delegation (2)
package Graduate;
use Moose;
extends qw/Student/;

has 'degree' => (
   isa => 'Degree',
   is => 'rw',
);
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
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 => 'IIii',
);
$g->degree($d);

print $g->graduated->year;
> 1985
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',
);
Attribute Helpers
my $st = Student->new( name => 'Mike' );

$st->classes(
    { "Compilers" => 'fail',
     "Numerical Methods" => 'pass' }
);

%{$st->classes}->{"Lisp"} = "pass";
Attribute Helpers (2)
use MooseX::AttributeHelpers;
has classes => (
    metaclass => 'Collection::Hash',
    isa => 'HashRef[Result]',
    is => 'rw',
    provides => {
        set => 'add_class',
        keys => 'list_classes',
    }
)
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
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->has_method("foo");
Introspecting Moose
• my $metaclass = $self->meta;

• $metaclass->superclasses;
• $metaclass->linearized_isa;
• $metaclass->has_method("foo");
• $metaclass->get_all_attributes;
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: MooseX::Method::Signature
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) {
        $self->schedule($time, $class);
    }
}
Even more Java-like?
use MooseX::Declare;

class Student extends Person with
Earnings {
   has 'id' => ( isa => 'StudentID' );

    method attend ( Str $class, ... ) {
        # yadda yadda
    }
}
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
• You don't need to know what's going on...
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 you don't have to"
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
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
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/col94.html
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:SQLite:dbname=s.db'
);
class_has _schema => (
    isa => 'Person::Schema',
    lazy_build => 1, is => 'ro',
);
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::General
         ->new( 'db.conf' )->getall();
     $args->{db} = $conf{db}
         if exists $conf{db};
};
Complex Example (5)
has _row => {
    isa => 'DBIx::Class::Row',
    lazy_build => 1,
}
sub _build__row {
    return shift->_schema
        ->resultset('Student')
        ->find($self->id);
}
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 happens here?
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 _schema, ALSO
    lazy_build
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
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!
But...
# What if the student's ID changes?

has 'id' => (
    isa => 'StudentID',
    is => 'rw',
    trigger => '_build__row',
);

More Related Content

What's hot

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
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helperslicejack
 
Banishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHPBanishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHPDavid Hayes
 
WordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressWordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressAlena Holligan
 
Bioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekingeBioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekingeProf. Wim Van Criekinge
 
Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Bozhidar Batsov
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodJeremy Kendall
 
Coffeescript: No really, it's just Javascript
Coffeescript: No really, it's just JavascriptCoffeescript: No really, it's just Javascript
Coffeescript: No really, it's just JavascriptBrian Mann
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018Adam Tomat
 
Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Karsten Dambekalns
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perlgarux
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then Howsfarmer10
 
Contando uma história com O.O.
Contando uma história com O.O.Contando uma história com O.O.
Contando uma história com O.O.Vagner Zampieri
 
Rails for PHP Developers
Rails for PHP DevelopersRails for PHP Developers
Rails for PHP DevelopersRobert Dempsey
 

What's hot (20)

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
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helper
 
Banishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHPBanishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHP
 
WordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPressWordCamp Portland 2018: PHP for WordPress
WordCamp Portland 2018: PHP for WordPress
 
Bioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekingeBioinformatics p5-bioperl v2013-wim_vancriekinge
Bioinformatics p5-bioperl v2013-wim_vancriekinge
 
Bioinformatica p6-bioperl
Bioinformatica p6-bioperlBioinformatica p6-bioperl
Bioinformatica p6-bioperl
 
Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)
 
Perl object ?
Perl object ?Perl object ?
Perl object ?
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the Good
 
Coffeescript: No really, it's just Javascript
Coffeescript: No really, it's just JavascriptCoffeescript: No really, it's just Javascript
Coffeescript: No really, it's just Javascript
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 
Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 
Searching ORM: First Why, Then How
Searching ORM: First Why, Then HowSearching ORM: First Why, Then How
Searching ORM: First Why, Then How
 
Contando uma história com O.O.
Contando uma história com O.O.Contando uma história com O.O.
Contando uma história com O.O.
 
Rails for PHP Developers
Rails for PHP DevelopersRails for PHP Developers
Rails for PHP Developers
 
Django at Scale
Django at ScaleDjango at Scale
Django at Scale
 

Similar to Introduction to Moose with Moose Roles and Types

Moo the universe and everything
Moo the universe and everythingMoo the universe and everything
Moo the universe and everythingHenry Van Styn
 
P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)lichtkind
 
Perl Teach-In (part 2)
Perl Teach-In (part 2)Perl Teach-In (part 2)
Perl Teach-In (part 2)Dave Cross
 
What's in a language? By Cheng Lou
What's in a language? By Cheng Lou What's in a language? By Cheng Lou
What's in a language? By Cheng Lou React London 2017
 
Moose - YAPC::NA 2012
Moose - YAPC::NA 2012Moose - YAPC::NA 2012
Moose - YAPC::NA 2012xSawyer
 
DBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たちDBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たちRyo Miyake
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsMatt Follett
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 
A Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::ClassA Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::ClassCurtis Poe
 
The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitStephen Scaffidi
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9sagaroceanic11
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9sagaroceanic11
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio Martín
 
Ruby :: Training 1
Ruby :: Training 1Ruby :: Training 1
Ruby :: Training 1Pavel Tyk
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new thingsDavid Black
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)RORLAB
 
From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scalatod esking
 
Objective C 基本介紹
Objective C 基本介紹Objective C 基本介紹
Objective C 基本介紹Giga Cheng
 
PHP-05-Objects.ppt
PHP-05-Objects.pptPHP-05-Objects.ppt
PHP-05-Objects.pptrani marri
 

Similar to Introduction to Moose with Moose Roles and Types (20)

Moo the universe and everything
Moo the universe and everythingMoo the universe and everything
Moo the universe and everything
 
P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)
 
Perl Teach-In (part 2)
Perl Teach-In (part 2)Perl Teach-In (part 2)
Perl Teach-In (part 2)
 
What's in a language? By Cheng Lou
What's in a language? By Cheng Lou What's in a language? By Cheng Lou
What's in a language? By Cheng Lou
 
Moose - YAPC::NA 2012
Moose - YAPC::NA 2012Moose - YAPC::NA 2012
Moose - YAPC::NA 2012
 
DBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たちDBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たち
 
Perl: Hate it for the Right Reasons
Perl: Hate it for the Right ReasonsPerl: Hate it for the Right Reasons
Perl: Hate it for the Right Reasons
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 
A Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::ClassA Whirlwind Tour of Test::Class
A Whirlwind Tour of Test::Class
 
The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's Toolkit
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9
 
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Ruby :: Training 1
Ruby :: Training 1Ruby :: Training 1
Ruby :: Training 1
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
 
Ruby 101
Ruby 101Ruby 101
Ruby 101
 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
 
From Ruby to Scala
From Ruby to ScalaFrom Ruby to Scala
From Ruby to Scala
 
Objective C 基本介紹
Objective C 基本介紹Objective C 基本介紹
Objective C 基本介紹
 
PHP-05-Objects.ppt
PHP-05-Objects.pptPHP-05-Objects.ppt
PHP-05-Objects.ppt
 

Recently uploaded

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
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
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 

Recently uploaded (20)

Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
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...
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 

Introduction to Moose with Moose Roles and Types