import moose website
[gitmo/moose-htdocs.git] / PTPW_2008 / practical_moose.s5
1 Title:        Moose
2 Location:     YAPC::Asia::2008
3 Presenter:    Yuval Kogman
4 Date:         2008
5 Theme:        moose
6
7 HAI FRENDS
8 ==========
9
10 * My name is Yuval
11
12 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
13
14 WHY AM I HERE?
15 ==============
16
17 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
18
19 <img src="porn/cog.jpg"  style="height: 75%">
20
21 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
22
23 <img src="porn/chamonix.jpg"  style="height: 75%">
24
25 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
26
27 <img src="porn/clkao.jpg"  style="height: 75%">
28
29 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
30
31 <img src="porn/office.jpg"  style="height: 75%">
32
33 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
34
35 <img src="porn/kitchen.jpg"  style="height: 75%">
36
37 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
38
39 <img src="porn/blood.jpg"  style="height: 75%">
40
41 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
42
43 <img src="porn/intestines.jpg"  style="height: 75%">
44
45 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
46
47 <img src="porn/duck_head.jpg" style="height: 75%">
48
49 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
50
51 <img src="porn/stinkytofu.jpg"  style="height: 75%">
52
53 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
54
55 <img src="porn/hunting.jpg"  style="height: 75%">
56
57 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
58
59 <img src="porn/tokyo.jpg" style="height: 75%">
60
61 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
62
63 <img src="porn/tokyo_crazy.jpg" style="height: 75%">
64
65 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
66
67 <img src="porn/uni.jpg"  style="height: 75%">
68
69 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
70
71 <img src="porn/vomit.jpg"  style="height: 75%">
72
73 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
74
75 <img src="porn/phone.jpg"  style="height: 75%">
76
77 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
78
79 <img src="porn/phone_no.jpg"  style="height: 75%">
80
81 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
82
83 <img src="porn/glasses.jpg"  style="height: 75%">
84
85 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
86
87 <img src="porn/glasses_no.jpg"  style="height: 75%">
88
89 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
90
91 <img src="porn/visa.jpg"  style="height: 75%">
92
93 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
94
95 <img src="porn/visa_no.jpg"  style="height: 75%">
96
97 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
98
99 <img src="porn/orz.jpg"  style="height: 50%">
100
101 <span style="font-family: sans-serif; font-weight: bold; font-size: 3em">orz orz orz </span>
102
103 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
104
105 <img src="porn/cog.jpg"  style="height: 75%">
106
107 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
108
109 <img src="porn/tubes.jpg"  style="height: 75%">
110
111 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
112
113 <img src="porn/jetpack.jpg"  style="height: 75%">
114
115 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
116
117 <img src="porn/food.jpg"  style="height: 75%">
118
119 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
120
121 <img src="porn/mousse.jpg"  style="height: 75%">
122
123 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
124
125 <img src="porn/beer.jpg"  style="height: 75%">
126
127 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
128
129 <img src="porn/zipbox.jpg" style="height: 75%">
130
131 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
132
133 <img src="porn/laundry.jpg"  style="height: 75%">
134
135 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
136
137 So here I am
138 ============
139
140 * Anyway…
141
142 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
143
144 Moose
145 =====
146
147 <img src="porn/moose_danger.jpg"  style="height: 75%">
148
149 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
150
151 Moose Is Not
152 ============
153
154 * Experimental
155 * A toy
156 * Just another accessor builder
157 * A source filter
158 * Perl black magic
159 * Perl 6 in Perl 5
160
161 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
162
163 Moose Is
164 ========
165
166 * <a href="http://moose.perl.org">http://moose.perl.org</a>
167 * A complete modern object framework for Perl
168
169 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
170
171 Moose Is
172 ========
173
174 * Syntactic Sugar for `Class::MOP`
175 * Rich ancestry
176     * CLOS (Common Lisp Object System)
177     * Smalltalk
178     * Alces latifrons
179     * Perl 6
180     * …
181 * Stable & Production ready
182 * Polite, incremental
183
184 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
185
186 A Simple Example
187 ================
188
189 <pre><code>
190 package Person;
191
192 use strict;
193 use warnings;
194
195 sub new {
196     my ( $class, @args ) = @_;
197
198     @args = %{$args[0]} if @args == 1;
199
200     return bless {
201         @args,
202     }, $class;
203 }
204
205 sub name {
206     my ($self, @args) = @_;
207     $self->{name} = $args[0] if @args;
208     return $self->{name};
209 }
210
211 sub age {
212     my ($self, @args) = @_;
213     $self->{age} = $args[0] if @args;
214     return $self->{age}; 
215 }
216
217 1;
218 </code></pre>
219
220 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
221
222 A Simple Moose Example
223 ======================
224
225 <pre><code>
226 package Person;
227 use Moose;
228
229 has name => (is => 'rw');
230 has age  => (is => 'rw');
231
232 1;
233 </code></pre>
234
235 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
236
237 A Simple Moose Example (cont.)
238 ==============================
239
240 * `use Moose;` 
241     * imports keywords
242     * `use strict; use warnings;`
243     * `@ISA = qw(Moose::Object) unless @ISA`
244
245 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
246
247 A Simple Moose Example (cont.)
248 ==============================
249
250 * `has` declares attributes
251     * generates accessors
252     * `is => 'rw'` → read/write accessor
253     * `is => 'ro'` → read only accessor
254     * `writer`, `reader`
255
256 * `new` inherited from `Moose::Object`
257
258
259 ##########
260
261 Now we're going to discuss more features of the attributes
262
263 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
264
265 Variations on a Moose Example
266 =============================
267
268 <pre><code>
269 package Manager;
270 use Moose;
271
272 has name => (
273     is  => 'rw',
274     isa => 'Str',
275     default => 'Bob'
276 );
277
278 has staff => (
279     is      => 'ro',
280     isa     => 'ArrayRef',
281     lazy    => 1,
282     default => sub { [qw(Bob Alice Tim)] },
283 );
284 </code></pre>
285 ##########
286
287 Adds default, isa
288
289 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
290
291 Variations on a Moose Example (cont.)
292 =====================================
293
294 * `default` is a
295     * code reference
296     * or non-reference (numbers, strings)
297     * used when no parameter is given to `new`
298
299 * `lazy` delays `default`
300     * called on first usage of `$object->staff`
301     * not inside `new`
302
303 ##########
304 discusses default
305
306 non refs make accidental sharing hard
307
308 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
309
310 Variations on a Moose Example (cont.)
311 =====================================
312
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
317 <pre><code>
318             has 'date' => (isa => 'DateTime'); # DWIM
319 </code></pre>
320 ##########
321
322 isa, type constraints
323
324 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
325
326 Typical Family
327 ==============
328
329 * Types have a hierarchy
330     * `Item` ⊃ `Defined` ⊃ `Ref` ⊃ `Object`
331
332 <pre><code>
333         subtype 'Ref'
334             => as 'Defined'
335             => where {  ref($_) };
336
337         subtype 'Object'
338             => as 'Ref'
339             => where { blessed($_) }
340 </code></pre>
341 ##########
342
343 type hierarchy
344
345 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
346
347 Conventional Delegates
348 ======================
349
350 <pre><code>
351 package Employee;
352 use Moose;
353 extends qw(Person);
354     
355 has manager =>  (
356     is  => 'ro',
357     isa => 'Manager',
358     handles => {
359         manager_name => 'name',
360         coworkers    => 'staff',
361     }
362 );
363 </code></pre>
364
365 * manager `handles` certain methods for `Employee`
366     * `$emp->coworkers` == `$emp->manager->staff `
367
368 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
369
370 Conventional Delegates (cont.)
371 ==============================
372
373 <pre><code>
374 has phone => (
375     ...
376     handles => [qw(number extension)],
377 );
378 </code></pre>
379
380 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
381
382 Conventional Delegates (cont.)
383 ==============================
384
385 <pre><code>
386 has phone => (
387     ...
388     isa     => "Phone",
389     handles => qr/^[a-z]\w+$/,
390 );
391 </code></pre>
392
393 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
394
395 Conventional Delegates (cont.)
396 ==============================
397
398 <pre><code>
399 has phone => (
400     ...
401     handles => "Dialing", # a role
402 );
403 </code></pre>
404
405 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
406
407 UnConventional Delegates
408 ========================
409
410 <pre><code>
411 package Company;
412 use Moose;
413 use MooseX::AttributeHelpers;
414    
415 has employees => (
416     metaclass => 'Collection::Array',
417     isa => 'ArrayRef[Employees]',
418     is  => 'rw',
419     provides => {
420         push  => 'add_employee',
421         pop   => 'remove_employee',
422         count => 'number_of_employees',
423         empty => 'any_employees',
424     },
425 );
426 </code></pre>
427 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
428
429 Modified Methods
430 ================
431
432 <pre><code>
433 before 'employees' => sub { warn 'calling employees' };
434
435 after 'employees' => sub { warn 'finished calling employees' };
436 </code></pre>
437
438 *  Pre/Post hooks
439     * Get a copy of `@_`
440     * Return value is ignored
441
442 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
443
444 Modified Methods (cont.)
445 ========================
446
447 <pre><code>
448 around 'employees' => sub { 
449     my ($next, $self, @args) = @_;
450     ...
451     my @return = $self->$next(@args);
452     ...
453     return @return;
454 };
455 </code></pre>
456
457 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
458
459 Modified Methods (cont.)
460 ========================
461
462 <pre><code>
463 package Employee;
464 use Moose;
465
466 sub do_work {
467     my $self = shift;
468     
469     $self->punch_in;
470     
471     inner(); # call subclass here
472     
473     $self->punch_out;
474 }
475 </code></pre>
476
477 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
478
479 Modified Methods (cont.)
480 ========================
481
482 <pre><code>
483 package Employee::Chef;
484 use Moose;
485
486 extends qw(Employee);
487
488 augment do_work => sub {
489     my $self = shift;
490     
491     while ( @burgers ) {
492         $self->flip_burger(shift @burgers);
493     }
494 };
495
496 $chef->do_work; # punch in, flip burgers, punch out
497 </code></pre>
498 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
499
500 Some Type of Coercion
501 =====================
502
503 <pre><code>
504 package Employee;
505 use Moose;
506 use Moose::Util::TypeConstraints;
507 extends qw(Person);
508
509 class_type 'Manager';
510
511 coerce 'Manager' => (
512     from 'Str' => via { Manager->new( name => $_ ) },
513 );
514
515 has manager => (
516     is => 'ro',
517     isa => 'Manager',
518     required => 1, 
519     coerce => 1,
520 );
521 </code></pre>
522
523 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
524
525 Some Type of Coercion (cont.)
526 =============================
527
528 <pre><code>
529 # import type constraint keywords
530 use Moose::Util::TypeConstraints;
531
532
533 # define Manager, a subtype of Object
534 class_type "Manager";
535
536
537 # define the conversion
538 ... via { Manager->new( name => $_ ) }
539
540
541 # enable it per attribute
542 has manager => (
543     ...
544     coerce => 1,
545 );
546 </code></pre>
547
548 ##########
549
550 breakdown of the example
551
552 class types are automatically created for all Moose classes
553
554 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
555
556 Some Type of Digression
557 =======================
558
559 <pre><code>
560 has employees => (
561     is => 'rw',
562     isa => 'ArrayRef[Employee]',
563 );
564
565 has shopping_carts => (
566     is => 'rw',
567     isa => 'ArrayRef[ArrayRef[ShinyBead]]'
568 );
569 </code></pre>
570
571 ##########
572
573 Going to go into features of the type system for a bit
574
575 Parametrized types
576
577 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
578 Some Type of Digression (cont.)
579 ===============================
580
581 <pre><code>
582 has language => (
583     is => 'rw',
584     isa => 'English | Welsh | Scots | Gaelic',
585 );  
586
587 has member => (
588     is => 'rw',
589     isa => 'Employee | ArrayRef[ Employee | Group ]',
590 );
591 </code></pre>
592
593 ##########
594
595 Union types
596
597 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
598
599 Some Type of Digression (cont.)
600 ===============================
601
602 <pre><code>
603 package Foo;
604 use Moose;
605 use Moose::Util::TypeConstraints;
606
607 use Test::Deep qw(eq_deeply ...);
608
609 type 'SomethingTricky' => where {
610     eq_deeply( $_, ... );
611 };
612
613 has 'bar' => (
614     is  => 'rw',
615     isa => 'SomethingTricky',
616 );
617 </code></pre>
618
619 ##########
620
621 Test::Deep custom validator
622
623 Can use any validation from the CPAN
624
625 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
626
627 Some Parametrized Type of Coercion
628 ==================================
629
630 <pre><code>
631 use Moose::Util::TypeConstraints;
632
633 subtype 'ArrayRef[Employee]' => as 'ArrayRef';
634
635 coerce 'ArrayRef[Employee]' => (
636     from 'ArrayRef[Str]' via {
637         [ map { Employee->new( name => $_ ) } @$_ ]
638     },
639 );
640
641 has staff => (
642     isa    => 'ArrayRef[Employee]',
643     coerce => 1,
644 );
645 </code></pre>
646
647 ##########
648
649 coerce parametrized ArrayRef[Employee] from ArrayRef[Str]
650
651 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
652
653 Role of the Moose 
654 =================
655
656 * A role is like a…
657     * Java Interface: safe
658     * mixin: useful
659 * A role is for small reusable behaviors
660     * better than using a multiple inheritence
661
662 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
663
664 Role of the Moose (cont.)
665 =========================
666
667 * Roles on the CPAN:
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,
673
674 ##########
675
676 Some examples of small reusable behaviors
677
678 Param is good for interacting with e.g. CGI::Expand or similar modules
679
680 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
681
682 Role of the Moose (cont.)
683 =========================
684
685 <pre><code>
686 package Minion;
687 use Moose;
688
689 extends qw(Employee);
690
691 with qw(Salaried::Hourly);
692
693
694 package Boss;
695 use Moose;
696
697 extends qw(Employee);
698
699 with qw(Salaried::Monthly);
700
701 </code></pre>
702
703 * `with` adds roles into your class
704     * `Salaried::Hourly` was added to `Minion`
705
706 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
707
708 Role of the Moose (cont.)
709 =========================
710
711 <pre><code>
712 package Salaried;
713 use Moose::Role;
714
715 requires 'paycheck_amount';
716 </code></pre>
717
718 * Just an interface
719
720 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
721
722 Role of the Moose (cont.)
723 =========================
724
725 <pre><code>
726 package Salaried::Hourly;
727 use Moose::Role;
728
729 with qw(Salaried);
730
731 has hourly_rate => (
732     isa => "Num",
733     is  => "rw",
734     required => 1,
735 );
736
737 has logged_hours => (
738     isa => "Num",
739     is  => "rw",
740     default => 0,
741 );
742
743 # satisfy the Salaried interface:
744 sub paycheck_amount {
745     my $self = shift;
746     $self->logged_hours * $self->hourly_rate;
747 }
748
749 </code></pre>
750
751 * More than an interface
752
753 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
754
755 Role of the Moose (cont.)
756 =========================
757
758 * More than Java Interfaces
759     * Interfaces are behavior "contracts"
760     * Roles can also have code
761
762 ##########
763 roles can have attributes and methods
764 roles provide behavior, not just interface
765
766 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
767
768 Role of the Moose (cont.)
769 =========================
770
771 * Role Composition
772     * Not inheritence
773     * Symmetric
774     * Unordered
775
776 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
777
778 Role of the Moose (cont.)
779 =========================
780
781 * Role Composition
782     * Less ambiguity
783     * Compile time errors
784     * …And ways to fix them
785
786 ##########
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
789
790 roles cause errors at compile time, unlike multiple inheritence
791
792 roles also provide easy ways to fix the errors
793
794 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
795
796 Role of the Moose (cont.)
797 =========================
798
799 <pre><code>
800 package Ballet;
801 use Moose::Role;
802
803 sub dance {
804     pirouette();
805 }
806
807 package Punk;
808 use Moose::Role
809
810 sub dance {
811     MOSH!!!11one();
812 }
813
814 package Foo;
815 use Moose;
816
817 # KABOOM:
818 with qw(
819     Punk
820     Ballet
821 );
822 </code></pre>
823
824 ##########
825
826 conflicts
827
828 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
829
830 Role of the Moose (cont.)
831 =========================
832
833 <pre><code>
834 package Ent::Puppy;
835 use Moose;
836
837 with (
838     Tree => {
839         alias => {
840             bark => "tree_bark",
841         },
842     },
843     Dog => {
844         alias => {
845             bark => "bark_sound",
846         }
847     },
848 );
849
850 sub bark {
851     my $self = shift;
852     
853     if ( $condition ) {
854         $self->tree_bark;
855     } else {
856         $self->bark_sound;
857     }
858 }
859 </code></pre>
860
861 * Not that common in practice
862  
863 ##########
864
865 Composition parameters
866 Easier conflict resolution
867 Finer grained control
868
869 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
870
871 MOPs Mean Cleanliness
872 =====================
873
874 * Moose is based on `Class::MOP`
875     * Metaobject Protocol for Perl 5
876     * "makes an object for everything"
877     
878 <pre><code>
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!
882
883 warn  $obj->meta->name;
884 </code></pre>
885
886 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
887
888 Looking in From the Inside
889 ===========================
890
891 <pre><code>
892 my $metaclass = $self->meta; 
893
894 $metaclass->superclasses;
895
896 $metaclass->linearized_isa;
897
898 $metaclass->has_method("foo");
899
900 $metaclass->compute_all_applicable_attributes;
901
902 # … lots more
903 </code></pre>
904 ##########
905
906 simple introspection
907
908 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
909
910 Looking in From the Inside (cont.)
911 ==================================
912
913 <pre><code>
914 Moose::Meta::Class->create( Bar =>
915       version      => '0.01',
916       superclasses => [ 'Foo' ],
917       attributes => [
918           Moose::Meta::Attribute->new( bar => ... ),
919           Moose::Meta::Attribute->new( baz => ... ),
920       ],
921       methods => {
922           calculate_bar => sub { ... },
923           construct_baz => sub { ... }
924       },
925 );
926
927 my $anon_meta = Moose::Meta::Class->create_anon_class( ... );
928 </code></pre>
929
930 ##########
931
932 Classes can be created programmatically
933 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
934
935 Looking in From the Inside (cont.)
936 ==================================
937
938 <pre><code>
939 has foo => ( is => "rw" );
940
941 __PACKAGE__->meta->add_attribute(
942     "foo",  
943     is => "rw",
944 );
945 </code></pre>
946
947 * Moose is just sugar
948     * The MOP does the hard work
949
950 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
951
952 The Metaclass Tango
953 ===================
954
955 * Metaclassses control class behavior
956
957 <pre><code>
958 has employees => (
959     metaclass => 'Collection::Array',
960     ...
961 );
962 </code></pre>
963
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`, …,
968
969 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
970
971 Working in the Meta Frame
972 =========================
973
974 * `$work` project:
975 * CMS for a flash website
976 * Content is in XML
977
978 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
979
980 Working in the Meta Frame (cont.)
981 =================================
982
983 * Step 1. use Moose
984 * Step 2. ???
985 * Step 3. Profit!
986
987 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
988
989 Working in the Meta Frame (cont.)
990 =================================
991
992 * Step 2.1. Client's XML schemas → Moose classes
993     * Automatic class definitions
994     * High level objects in runtime
995     * XML storage backed
996         * SAX → Moose
997         * Moose → SAX
998
999 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1000
1001 Working in the Meta Frame (cont.)
1002 =================================
1003
1004 * Step 2.2. Meta descriptions
1005     * Extend the metaclasses
1006     * Embed additional information
1007         * field types
1008         * access control
1009
1010 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1011
1012 Working in the Meta Frame (cont.)
1013 =================================
1014
1015 * Step 2.3 Introspection goodness
1016     * Generic web frontend
1017     * Object introspection based
1018         * HTML view
1019         * Editing widgets
1020     * Clean, extensible
1021
1022 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1023
1024 Drawbacks of Moose
1025 ==================
1026
1027 * Load time
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`
1033
1034 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1035
1036 Benefits of Moose
1037 =================
1038
1039 * Less boilerplate
1040     * attribute storage/access
1041     * construction
1042     * destruction
1043     * verification
1044     * …
1045
1046 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1047
1048 Benefits of Moose (cont.)
1049 =========================
1050
1051 * Shorter
1052     * less reading
1053     * less writing
1054     * less code means fewer bugs
1055
1056 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1057
1058 Benefits of Moose (cont.)
1059 =========================
1060
1061 * Less testing
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
1067
1068 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1069
1070 Benefits of Moose (cont.)
1071 =========================
1072
1073 * More readable
1074     * declarative style is self documenting
1075     * good signal to noise ratio
1076
1077 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1078
1079 Benefits of Moose (cont.)
1080 =========================
1081
1082 * Meta object protocol
1083     * Cleans up Perl's OO
1084     * Provides introspection
1085     * Enables powerful abstractions
1086
1087 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1088
1089 Benefits of Moose (cont.)
1090 =========================
1091
1092 * It's the new black
1093     * All the cool kids hang out on #moose
1094     * Smart sounding buzzwords
1095     * Chicks dig antlers
1096     * Ruby is so 2007
1097
1098 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1099
1100 Bonus Material
1101 ==============
1102
1103 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1104
1105 Autobox
1106 =======
1107
1108 <pre><code>
1109 package Units::Bytes;
1110 use Moose::Role;
1111 use Moose::Autobox;
1112
1113 sub bytes     { $_[0]                   }
1114 sub kilobytes { $_[0] * 1024            }
1115 sub megabytes { $_[0] * 1024->kilobytes }
1116 sub gigabytes { $_[0] * 1024->megabytes }
1117 sub terabytes { $_[0] * 1024->gigabytes }
1118
1119 Moose::Autobox->mixin_additional_role(
1120     SCALAR => 'Units::Bytes',
1121 );
1122 </code></pre>
1123
1124 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1125
1126 Autobox (cont.)
1127 ===============
1128
1129 <pre><code>
1130 use Units::Bytes;
1131 use Moose::Autobox; # autoboxing is lexical
1132
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');
1138 </code></pre>
1139
1140 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1141
1142 perl -Moose
1143 ===========
1144
1145 * Moose One Liners with `oose.pm`
1146
1147 <pre><code>
1148 perl -Moose -e 'has foo => ( is=> "rw" ); Class->new( foo => 1 )'
1149 </code></pre>
1150
1151 * Useful for testing if something works
1152 * Helpful on IRC
1153 * `Devel::REPL` is cooler though ;-)
1154
1155 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1156
1157 MooseX::POE
1158 ===========
1159
1160 <pre><code>
1161 package Counter;
1162 use MooseX::POE;
1163 use MooseX::AttributeHelpers;
1164
1165 has count => (
1166     metaclass => 'Counter',
1167     provides => { inc => "increment_count" },
1168 );
1169
1170 sub START {
1171     shift->yield('increment');
1172 }
1173
1174 event increment => sub {
1175     my $self = shift;
1176
1177     warn "Count is now " . $self->count;
1178
1179     $self->increment_count;
1180     $self->yield('increment') unless $self->count > 3;
1181 };
1182
1183 Counter->new( count => 0 );
1184 POE::Kernel->run();
1185 </code></pre>
1186
1187 * PoCos made easy
1188 * Every object has a `POE::Session`
1189 * `event` declares POE object states
1190
1191 ✂------✂------✂------✂------✂------✂------✂------✂------✂------✂------
1192
1193 Fin
1194 ===
1195
1196 * Slides written by:
1197     * Chris Prather
1198     * Stevan Little
1199     * Robert Boone
1200
1201 * Slides deleted by:
1202     * Yuval Kogman