2 Location: YAPC::Asia::2008
3 Presenter: Yuval Kogman
12 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
17 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
19 <img src="porn/cog.jpg" style="height: 75%">
21 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
23 <img src="porn/chamonix.jpg" style="height: 75%">
25 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
27 <img src="porn/clkao.jpg" style="height: 75%">
29 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
31 <img src="porn/office.jpg" style="height: 75%">
33 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
35 <img src="porn/kitchen.jpg" style="height: 75%">
37 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
39 <img src="porn/blood.jpg" style="height: 75%">
41 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
43 <img src="porn/intestines.jpg" style="height: 75%">
45 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
47 <img src="porn/duck_head.jpg" style="height: 75%">
49 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
51 <img src="porn/stinkytofu.jpg" style="height: 75%">
53 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
55 <img src="porn/hunting.jpg" style="height: 75%">
57 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
59 <img src="porn/tokyo.jpg" style="height: 75%">
61 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
63 <img src="porn/tokyo_crazy.jpg" style="height: 75%">
65 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
67 <img src="porn/uni.jpg" style="height: 75%">
69 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
71 <img src="porn/vomit.jpg" style="height: 75%">
73 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
75 <img src="porn/phone.jpg" style="height: 75%">
77 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
79 <img src="porn/phone_no.jpg" style="height: 75%">
81 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
83 <img src="porn/glasses.jpg" style="height: 75%">
85 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
87 <img src="porn/glasses_no.jpg" style="height: 75%">
89 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
91 <img src="porn/visa.jpg" style="height: 75%">
93 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
95 <img src="porn/visa_no.jpg" style="height: 75%">
97 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
99 <img src="porn/orz.jpg" style="height: 50%">
101 <span style="font-family: sans-serif; font-weight: bold; font-size: 3em">orz orz orz </span>
103 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
105 <img src="porn/cog.jpg" style="height: 75%">
107 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
109 <img src="porn/tubes.jpg" style="height: 75%">
111 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
113 <img src="porn/jetpack.jpg" style="height: 75%">
115 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
117 <img src="porn/food.jpg" style="height: 75%">
119 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
121 <img src="porn/mousse.jpg" style="height: 75%">
123 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
125 <img src="porn/beer.jpg" style="height: 75%">
127 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
129 <img src="porn/zipbox.jpg" style="height: 75%">
131 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
133 <img src="porn/laundry.jpg" style="height: 75%">
135 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
142 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
147 <img src="porn/moose_danger.jpg" style="height: 75%">
149 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
156 * Just another accessor builder
161 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
166 * <a href="http://moose.perl.org">http://moose.perl.org</a>
167 * A complete modern object framework for Perl
169 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
174 * Syntactic Sugar for `Class::MOP`
176 * CLOS (Common Lisp Object System)
181 * Stable & Production ready
182 * Polite, incremental
184 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
196 my ( $class, @args ) = @_;
198 @args = %{$args[0]} if @args == 1;
206 my ($self, @args) = @_;
207 $self->{name} = $args[0] if @args;
208 return $self->{name};
212 my ($self, @args) = @_;
213 $self->{age} = $args[0] if @args;
220 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
222 A Simple Moose Example
223 ======================
229 has name => (is => 'rw');
230 has age => (is => 'rw');
235 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
237 A Simple Moose Example (cont.)
238 ==============================
242 * `use strict; use warnings;`
243 * `@ISA = qw(Moose::Object) unless @ISA`
245 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
247 A Simple Moose Example (cont.)
248 ==============================
250 * `has` declares attributes
251 * generates accessors
252 * `is => 'rw'` → read/write accessor
253 * `is => 'ro'` → read only accessor
256 * `new` inherited from `Moose::Object`
261 Now we're going to discuss more features of the attributes
263 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
265 Variations on a Moose Example
266 =============================
282 default => sub { [qw(Bob Alice Tim)] },
289 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
291 Variations on a Moose Example (cont.)
292 =====================================
296 * or non-reference (numbers, strings)
297 * used when no parameter is given to `new`
299 * `lazy` delays `default`
300 * called on first usage of `$object->staff`
306 non refs make accidental sharing hard
308 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
310 Variations on a Moose Example (cont.)
311 =====================================
313 * `isa` specifies a type
314 * `Moose::Util::TypeConstraints`
315 * `Any, Item, Bool, Undef, Defined, Value, Num, Int, Str, Ref, ScalarRef, ArrayRef, HashRef, CodeRef, RegexpRef, GlobRef, FileHandle, Object and Role`
316 * Types don't need to exist
318 has 'date' => (isa => 'DateTime'); # DWIM
322 isa, type constraints
324 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
329 * Types have a hierarchy
330 * `Item` ⊃ `Defined` ⊃ `Ref` ⊃ `Object`
335 => where { ref($_) };
339 => where { blessed($_) }
345 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
347 Conventional Delegates
348 ======================
359 manager_name => 'name',
360 coworkers => 'staff',
365 * manager `handles` certain methods for `Employee`
366 * `$emp->coworkers` == `$emp->manager->staff `
368 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
370 Conventional Delegates (cont.)
371 ==============================
376 handles => [qw(number extension)],
380 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
382 Conventional Delegates (cont.)
383 ==============================
389 handles => qr/^[a-z]\w+$/,
393 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
395 Conventional Delegates (cont.)
396 ==============================
401 handles => "Dialing", # a role
405 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
407 UnConventional Delegates
408 ========================
413 use MooseX::AttributeHelpers;
416 metaclass => 'Collection::Array',
417 isa => 'ArrayRef[Employees]',
420 push => 'add_employee',
421 pop => 'remove_employee',
422 count => 'number_of_employees',
423 empty => 'any_employees',
427 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
433 before 'employees' => sub { warn 'calling employees' };
435 after 'employees' => sub { warn 'finished calling employees' };
440 * Return value is ignored
442 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
444 Modified Methods (cont.)
445 ========================
448 around 'employees' => sub {
449 my ($next, $self, @args) = @_;
451 my @return = $self->$next(@args);
457 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
459 Modified Methods (cont.)
460 ========================
471 inner(); # call subclass here
477 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
479 Modified Methods (cont.)
480 ========================
483 package Employee::Chef;
486 extends qw(Employee);
488 augment do_work => sub {
492 $self->flip_burger(shift @burgers);
496 $chef->do_work; # punch in, flip burgers, punch out
498 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
500 Some Type of Coercion
501 =====================
506 use Moose::Util::TypeConstraints;
509 class_type 'Manager';
511 coerce 'Manager' => (
512 from 'Str' => via { Manager->new( name => $_ ) },
523 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
525 Some Type of Coercion (cont.)
526 =============================
529 # import type constraint keywords
530 use Moose::Util::TypeConstraints;
533 # define Manager, a subtype of Object
534 class_type "Manager";
537 # define the conversion
538 ... via { Manager->new( name => $_ ) }
541 # enable it per attribute
550 breakdown of the example
552 class types are automatically created for all Moose classes
554 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
556 Some Type of Digression
557 =======================
562 isa => 'ArrayRef[Employee]',
565 has shopping_carts => (
567 isa => 'ArrayRef[ArrayRef[ShinyBead]]'
573 Going to go into features of the type system for a bit
577 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
578 Some Type of Digression (cont.)
579 ===============================
584 isa => 'English | Welsh | Scots | Gaelic',
589 isa => 'Employee | ArrayRef[ Employee | Group ]',
597 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
599 Some Type of Digression (cont.)
600 ===============================
605 use Moose::Util::TypeConstraints;
607 use Test::Deep qw(eq_deeply ...);
609 type 'SomethingTricky' => where {
610 eq_deeply( $_, ... );
615 isa => 'SomethingTricky',
621 Test::Deep custom validator
623 Can use any validation from the CPAN
625 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
627 Some Parametrized Type of Coercion
628 ==================================
631 use Moose::Util::TypeConstraints;
633 subtype 'ArrayRef[Employee]' => as 'ArrayRef';
635 coerce 'ArrayRef[Employee]' => (
636 from 'ArrayRef[Str]' via {
637 [ map { Employee->new( name => $_ ) } @$_ ]
642 isa => 'ArrayRef[Employee]',
649 coerce parametrized ArrayRef[Employee] from ArrayRef[Str]
651 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
657 * Java Interface: safe
659 * A role is for small reusable behaviors
660 * better than using a multiple inheritence
662 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
664 Role of the Moose (cont.)
665 =========================
668 * `MooseX::Clone` - Flexible `clone` method
669 * `MooseX::Storage` - Flexible serialization
670 * `MooseX::Getopt` - `@ARGV` aware constructor
671 * `MooseX::LogDispatch` - `$self->logger->info("something happenned")`
672 * `MooseX::Param` - `param` method like `CGI.pm`'s,
676 Some examples of small reusable behaviors
678 Param is good for interacting with e.g. CGI::Expand or similar modules
680 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
682 Role of the Moose (cont.)
683 =========================
689 extends qw(Employee);
691 with qw(Salaried::Hourly);
697 extends qw(Employee);
699 with qw(Salaried::Monthly);
703 * `with` adds roles into your class
704 * `Salaried::Hourly` was added to `Minion`
706 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
708 Role of the Moose (cont.)
709 =========================
715 requires 'paycheck_amount';
720 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
722 Role of the Moose (cont.)
723 =========================
726 package Salaried::Hourly;
737 has logged_hours => (
743 # satisfy the Salaried interface:
744 sub paycheck_amount {
746 $self->logged_hours * $self->hourly_rate;
751 * More than an interface
753 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
755 Role of the Moose (cont.)
756 =========================
758 * More than Java Interfaces
759 * Interfaces are behavior "contracts"
760 * Roles can also have code
763 roles can have attributes and methods
764 roles provide behavior, not just interface
766 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
768 Role of the Moose (cont.)
769 =========================
776 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
778 Role of the Moose (cont.)
779 =========================
783 * Compile time errors
784 * …And ways to fix them
787 symmetric composition means no precedence - if two roles try to define the same thing you get a compile time error that needs to be resolved
788 multiple inheritence silently assumes you want the first class
790 roles cause errors at compile time, unlike multiple inheritence
792 roles also provide easy ways to fix the errors
794 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
796 Role of the Moose (cont.)
797 =========================
828 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
830 Role of the Moose (cont.)
831 =========================
845 bark => "bark_sound",
861 * Not that common in practice
865 Composition parameters
866 Easier conflict resolution
867 Finer grained control
869 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
871 MOPs Mean Cleanliness
872 =====================
874 * Moose is based on `Class::MOP`
875 * Metaobject Protocol for Perl 5
876 * "makes an object for everything"
879 my $class = $obj->meta; # $obj's metaclass
880 my $meta = MyApp->meta; # MyApp's metaclass
881 my $emo = $obj->meta->meta; # even more meta!
883 warn $obj->meta->name;
886 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
888 Looking in From the Inside
889 ===========================
892 my $metaclass = $self->meta;
894 $metaclass->superclasses;
896 $metaclass->linearized_isa;
898 $metaclass->has_method("foo");
900 $metaclass->compute_all_applicable_attributes;
908 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
910 Looking in From the Inside (cont.)
911 ==================================
914 Moose::Meta::Class->create( Bar =>
916 superclasses => [ 'Foo' ],
918 Moose::Meta::Attribute->new( bar => ... ),
919 Moose::Meta::Attribute->new( baz => ... ),
922 calculate_bar => sub { ... },
923 construct_baz => sub { ... }
927 my $anon_meta = Moose::Meta::Class->create_anon_class( ... );
932 Classes can be created programmatically
933 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
935 Looking in From the Inside (cont.)
936 ==================================
939 has foo => ( is => "rw" );
941 __PACKAGE__->meta->add_attribute(
947 * Moose is just sugar
948 * The MOP does the hard work
950 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
955 * Metaclassses control class behavior
959 metaclass => 'Collection::Array',
964 * custom attribute metaclasses
965 * change how attributes work
966 * Many customizable parts
967 * `Moose::Meta::Class`, `Moose::Meta::Attribute, ``Moose::Meta::Method`, `Moose::Meta::Method::Accessor` `Moose::Meta::Instance`, `Moose::Meta::Role`, `Moose::Meta::TypeConstraint`, …,
969 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
971 Working in the Meta Frame
972 =========================
975 * CMS for a flash website
978 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
980 Working in the Meta Frame (cont.)
981 =================================
987 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
989 Working in the Meta Frame (cont.)
990 =================================
992 * Step 2.1. Client's XML schemas → Moose classes
993 * Automatic class definitions
994 * High level objects in runtime
999 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1001 Working in the Meta Frame (cont.)
1002 =================================
1004 * Step 2.2. Meta descriptions
1005 * Extend the metaclasses
1006 * Embed additional information
1010 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1012 Working in the Meta Frame (cont.)
1013 =================================
1015 * Step 2.3 Introspection goodness
1016 * Generic web frontend
1017 * Object introspection based
1022 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1028 * `MooseX::Compile` is in the works
1029 * Some features are slow
1030 * but you only pay for what you use
1031 * Extending non-Hash based classes is tricky.
1032 * but possible: `MooseX::GlobRef::Object`
1034 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1040 * attribute storage/access
1046 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1048 Benefits of Moose (cont.)
1049 =========================
1054 * less code means fewer bugs
1056 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1058 Benefits of Moose (cont.)
1059 =========================
1062 * Moose is very well tested
1063 * no need to check accessor behavior, etc
1064 * focus on your code's purpose
1065 * not that it is "assembled" correctly
1066 * http://c2.com/cgi/wiki?IntentionNotAlgorithm
1068 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1070 Benefits of Moose (cont.)
1071 =========================
1074 * declarative style is self documenting
1075 * good signal to noise ratio
1077 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1079 Benefits of Moose (cont.)
1080 =========================
1082 * Meta object protocol
1083 * Cleans up Perl's OO
1084 * Provides introspection
1085 * Enables powerful abstractions
1087 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1089 Benefits of Moose (cont.)
1090 =========================
1092 * It's the new black
1093 * All the cool kids hang out on #moose
1094 * Smart sounding buzzwords
1095 * Chicks dig antlers
1098 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1103 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1109 package Units::Bytes;
1114 sub kilobytes { $_[0] * 1024 }
1115 sub megabytes { $_[0] * 1024->kilobytes }
1116 sub gigabytes { $_[0] * 1024->megabytes }
1117 sub terabytes { $_[0] * 1024->gigabytes }
1119 Moose::Autobox->mixin_additional_role(
1120 SCALAR => 'Units::Bytes',
1124 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1131 use Moose::Autobox; # autoboxing is lexical
1133 is(5->bytes, 5, '... got 5 bytes');
1134 is(5->kilobytes, 5120, '... got 5 kilobytes');
1135 is(2->megabytes, 2097152, '... got 2 megabytes');
1136 is(1->gigabytes, 1073741824, '... got 1 gigabyte');
1137 is(2->terabytes, 2199023255552, '... got 2 terabytes');
1140 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1145 * Moose One Liners with `oose.pm`
1148 perl -Moose -e 'has foo => ( is=> "rw" ); Class->new( foo => 1 )'
1151 * Useful for testing if something works
1153 * `Devel::REPL` is cooler though ;-)
1155 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1163 use MooseX::AttributeHelpers;
1166 metaclass => 'Counter',
1167 provides => { inc => "increment_count" },
1171 shift->yield('increment');
1174 event increment => sub {
1177 warn "Count is now " . $self->count;
1179 $self->increment_count;
1180 $self->yield('increment') unless $self->count > 3;
1183 Counter->new( count => 0 );
1188 * Every object has a `POE::Session`
1189 * `event` declares POE object states
1191 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1196 * Slides written by:
1201 * Slides deleted by: