Move stevan's PPW slides
[gitmo/moose-website.git] / PTPW_2008 / practical_moose.html
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <html xmlns="http://www.w3.org/1999/xhtml">
6
7 <head>
8 <title>Moose</title>
9 <!-- metadata -->
10 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
11 <meta name="generator" content="TextMate/S5" />
12 <meta name="version" content="S5 1.2a2" />
13 <meta name="presdate" content="2008" />
14 <meta name="author" content="Yuval Kogman" />
15 <meta name="company" content="" />
16 <!-- configuration parameters -->
17 <meta name="defaultView" content="slideshow" />
18 <meta name="controlVis" content="visible" />
19 <!-- style sheet links -->
20 <link rel="stylesheet" href="./ui/moose/slides.css" type="text/css" media="projection" id="slideProj" />
21 <link rel="stylesheet" href="./ui/moose/outline.css" type="text/css" media="screen" id="outlineStyle" />
22 <link rel="stylesheet" href="./ui/moose/print.css" type="text/css" media="print" id="slidePrint" />
23 <link rel="stylesheet" href="./ui/moose/opera.css" type="text/css" media="projection" id="operaFix" />
24 <!-- embedded styles -->
25 <style type="text/css" media="all">
26 .imgcon {width: 525px; margin: 0 auto; padding: 0; text-align: center;}
27 #anim {width: 270px; height: 320px; position: relative; margin-top: 0.5em;}
28 #anim img {position: absolute; top: 42px; left: 24px;}
29 img#me01 {top: 0; left: 0;}
30 img#me02 {left: 23px;}
31 img#me04 {top: 44px;}
32 img#me05 {top: 43px;left: 36px;}
33 </style>
34 <!-- S5 JS -->
35 <script src="./ui/moose/slides.js" type="text/javascript"></script>
36 </head>
37 <body>
38
39 <div class="layout">
40 <div id="controls"><!-- DO NOT EDIT --></div>
41 <div id="currentSlide"><!-- DO NOT EDIT --></div>
42 <div id="header"></div>
43 <div id="footer">
44 <h1>YAPC::Asia::2008</h1>
45 <h2>Moose</h2>
46 </div>
47 <div class="topleft"></div>
48 <div class="topright"></div>
49 <div class="bottomleft"></div>
50 <div class="bottomright"></div>
51 </div>
52
53 <div class="presentation">
54
55 <div class="slide">
56 <h1>Moose</h1>
57 <h2></h2>
58 <h3>Yuval Kogman</h3>
59 <h4></h4>
60 </div>
61
62
63 <div class="slide">
64 <h1>HAI FRENDS</h1>
65
66 <ul>
67 <li>My name is Yuval</li>
68 </ul>
69
70 </div>
71
72 <div class="slide">
73 <h1>WHY AM I HERE?</h1>
74
75 </div>
76
77 <div class="slide">
78 <p><img src="porn/cog.jpg"  style="height: 75%"></p>
79
80 </div>
81
82 <div class="slide">
83 <p><img src="porn/chamonix.jpg"  style="height: 75%"></p>
84
85 </div>
86
87 <div class="slide">
88 <p><img src="porn/clkao.jpg"  style="height: 75%"></p>
89
90 </div>
91
92 <div class="slide">
93 <p><img src="porn/office.jpg"  style="height: 75%"></p>
94
95 </div>
96
97 <div class="slide">
98 <p><img src="porn/kitchen.jpg"  style="height: 75%"></p>
99
100 </div>
101
102 <div class="slide">
103 <p><img src="porn/blood.jpg"  style="height: 75%"></p>
104
105 </div>
106
107 <div class="slide">
108 <p><img src="porn/intestines.jpg"  style="height: 75%"></p>
109
110 </div>
111
112 <div class="slide">
113 <p><img src="porn/duck_head.jpg" style="height: 75%"></p>
114
115 </div>
116
117 <div class="slide">
118 <p><img src="porn/stinkytofu.jpg"  style="height: 75%"></p>
119
120 </div>
121
122 <div class="slide">
123 <p><img src="porn/hunting.jpg"  style="height: 75%"></p>
124
125 </div>
126
127 <div class="slide">
128 <p><img src="porn/tokyo.jpg" style="height: 75%"></p>
129
130 </div>
131
132 <div class="slide">
133 <p><img src="porn/tokyo_crazy.jpg" style="height: 75%"></p>
134
135 </div>
136
137 <div class="slide">
138 <p><img src="porn/uni.jpg"  style="height: 75%"></p>
139
140 </div>
141
142 <div class="slide">
143 <p><img src="porn/vomit.jpg"  style="height: 75%"></p>
144
145 </div>
146
147 <div class="slide">
148 <p><img src="porn/phone.jpg"  style="height: 75%"></p>
149
150 </div>
151
152 <div class="slide">
153 <p><img src="porn/phone_no.jpg"  style="height: 75%"></p>
154
155 </div>
156
157 <div class="slide">
158 <p><img src="porn/glasses.jpg"  style="height: 75%"></p>
159
160 </div>
161
162 <div class="slide">
163 <p><img src="porn/glasses_no.jpg"  style="height: 75%"></p>
164
165 </div>
166
167 <div class="slide">
168 <p><img src="porn/visa.jpg"  style="height: 75%"></p>
169
170 </div>
171
172 <div class="slide">
173 <p><img src="porn/visa_no.jpg"  style="height: 75%"></p>
174
175 </div>
176
177 <div class="slide">
178 <p><img src="porn/orz.jpg"  style="height: 50%"></p>
179
180 <p><span style="font-family: sans-serif; font-weight: bold; font-size: 3em">orz orz orz </span></p>
181
182 </div>
183
184 <div class="slide">
185 <p><img src="porn/cog.jpg"  style="height: 75%"></p>
186
187 </div>
188
189 <div class="slide">
190 <p><img src="porn/tubes.jpg"  style="height: 75%"></p>
191
192 </div>
193
194 <div class="slide">
195 <p><img src="porn/jetpack.jpg"  style="height: 75%"></p>
196
197 </div>
198
199 <div class="slide">
200 <p><img src="porn/food.jpg"  style="height: 75%"></p>
201
202 </div>
203
204 <div class="slide">
205 <p><img src="porn/mousse.jpg"  style="height: 75%"></p>
206
207 </div>
208
209 <div class="slide">
210 <p><img src="porn/beer.jpg"  style="height: 75%"></p>
211
212 </div>
213
214 <div class="slide">
215 <p><img src="porn/zipbox.jpg" style="height: 75%"></p>
216
217 </div>
218
219 <div class="slide">
220 <p><img src="porn/laundry.jpg"  style="height: 75%"></p>
221
222 </div>
223
224 <div class="slide">
225 <h1>So here I am</h1>
226
227 <ul>
228 <li>Anyway…</li>
229 </ul>
230
231 </div>
232
233 <div class="slide">
234 <h1>Moose</h1>
235
236 <p><img src="porn/moose_danger.jpg"  style="height: 75%"></p>
237
238 </div>
239
240 <div class="slide">
241 <h1>Moose Is Not</h1>
242
243 <ul>
244 <li>Experimental</li>
245 <li>A toy</li>
246 <li>Just another accessor builder</li>
247 <li>A source filter</li>
248 <li>Perl black magic</li>
249 <li>Perl 6 in Perl 5</li>
250 </ul>
251
252 </div>
253
254 <div class="slide">
255 <h1>Moose Is</h1>
256
257 <ul>
258 <li><a href="http://moose.perl.org">http://moose.perl.org</a></li>
259 <li>A complete modern object framework for Perl</li>
260 </ul>
261
262 </div>
263
264 <div class="slide">
265 <h1>Moose Is</h1>
266
267 <ul>
268 <li>Syntactic Sugar for <code>Class::MOP</code></li>
269 <li>Rich ancestry
270 <ul>
271 <li>CLOS (Common Lisp Object System)</li>
272 <li>Smalltalk</li>
273 <li>Alces latifrons</li>
274 <li>Perl 6</li>
275 <li>…</li>
276 </ul></li>
277 <li>Stable &amp; Production ready</li>
278 <li>Polite, incremental</li>
279 </ul>
280
281 </div>
282
283 <div class="slide">
284 <h1>A Simple Example</h1>
285
286 <pre><code>
287 package Person;
288
289 use strict;
290 use warnings;
291
292 sub new {
293     my ( $class, @args ) = @_;
294
295     @args = %{$args[0]} if @args == 1;
296
297     return bless {
298         @args,
299     }, $class;
300 }
301
302 sub name {
303     my ($self, @args) = @_;
304     $self->{name} = $args[0] if @args;
305     return $self->{name};
306 }
307
308 sub age {
309     my ($self, @args) = @_;
310     $self->{age} = $args[0] if @args;
311     return $self->{age}; 
312 }
313
314 1;
315 </code></pre>
316
317 </div>
318
319 <div class="slide">
320 <h1>A Simple Moose Example</h1>
321
322 <pre><code>
323 package Person;
324 use Moose;
325
326 has name => (is => 'rw');
327 has age  => (is => 'rw');
328
329 1;
330 </code></pre>
331
332 </div>
333
334 <div class="slide">
335 <h1>A Simple Moose Example (cont.)</h1>
336
337 <ul>
338 <li><code>use Moose;</code> 
339 <ul>
340 <li>imports keywords</li>
341 <li><code>use strict; use warnings;</code></li>
342 <li><code>@ISA = qw(Moose::Object) unless @ISA</code></li>
343 </ul></li>
344 </ul>
345
346 </div>
347
348 <div class="slide">
349 <h1>A Simple Moose Example (cont.)</h1>
350
351 <ul>
352 <li><p><code>has</code> declares attributes</p>
353
354 <ul>
355 <li>generates accessors</li>
356 <li><code>is =&gt; 'rw'</code> → read/write accessor</li>
357 <li><code>is =&gt; 'ro'</code> → read only accessor</li>
358 <li><code>writer</code>, <code>reader</code></li>
359 </ul></li>
360 <li><p><code>new</code> inherited from <code>Moose::Object</code></p></li>
361 </ul>
362
363 <div class="notes">
364 <p>Now we&#8217;re going to discuss more features of the attributes</p>
365 </div>
366 </div>
367
368 <div class="slide">
369 <h1>Variations on a Moose Example</h1>
370
371 <pre><code>
372 package Manager;
373 use Moose;
374
375 has name => (
376     is  => 'rw',
377     isa => 'Str',
378     default => 'Bob'
379 );
380
381 has staff => (
382     is      => 'ro',
383     isa     => 'ArrayRef',
384     lazy    => 1,
385     default => sub { [qw(Bob Alice Tim)] },
386 );
387 </code></pre>
388
389 <div class="notes">
390 <p>Adds default, isa</p>
391 </div>
392 </div>
393
394 <div class="slide">
395 <h1>Variations on a Moose Example (cont.)</h1>
396
397 <ul>
398 <li><p><code>default</code> is a</p>
399
400 <ul>
401 <li>code reference</li>
402 <li>or non-reference (numbers, strings)</li>
403 <li>used when no parameter is given to <code>new</code></li>
404 </ul></li>
405 <li><p><code>lazy</code> delays <code>default</code></p>
406
407 <ul>
408 <li>called on first usage of <code>$object-&gt;staff</code></li>
409 <li>not inside <code>new</code></li>
410 </ul></li>
411 </ul>
412
413 <div class="notes">
414 <p>discusses default</p>
415
416 <p>non refs make accidental sharing hard</p>
417 </div>
418 </div>
419
420 <div class="slide">
421 <h1>Variations on a Moose Example (cont.)</h1>
422
423 <ul>
424 <li><code>isa</code> specifies a type
425 <ul>
426 <li><code>Moose::Util::TypeConstraints</code>
427 <ul>
428 <li><code>Any, Item, Bool, Undef, Defined, Value, Num, Int, Str, Ref, ScalarRef, ArrayRef, HashRef, CodeRef, RegexpRef, GlobRef, FileHandle, Object and Role</code></li>
429 </ul></li>
430 <li>Types don&#8217;t need to exist</li>
431 </ul></li>
432 </ul>
433
434 <pre><code>
435             has 'date' => (isa => 'DateTime'); # DWIM
436 </code></pre>
437
438 <div class="notes">
439 <p>isa, type constraints</p>
440 </div>
441 </div>
442
443 <div class="slide">
444 <h1>Typical Family</h1>
445
446 <ul>
447 <li>Types have a hierarchy
448 <ul>
449 <li><code>Item</code> ⊃ <code>Defined</code> ⊃ <code>Ref</code> ⊃ <code>Object</code></li>
450 </ul></li>
451 </ul>
452
453 <pre><code>
454         subtype 'Ref'
455             => as 'Defined'
456             => where {  ref($_) };
457
458         subtype 'Object'
459             => as 'Ref'
460             => where { blessed($_) }
461 </code></pre>
462
463 <div class="notes">
464 <p>type hierarchy</p>
465 </div>
466 </div>
467
468 <div class="slide">
469 <h1>Conventional Delegates</h1>
470
471 <pre><code>
472 package Employee;
473 use Moose;
474 extends qw(Person);
475
476 has manager =>  (
477     is  => 'ro',
478     isa => 'Manager',
479     handles => {
480         manager_name => 'name',
481         coworkers    => 'staff',
482     }
483 );
484 </code></pre>
485
486 <ul>
487 <li>manager <code>handles</code> certain methods for <code>Employee</code>
488 <ul>
489 <li><code>$emp-&gt;coworkers</code> == <code>$emp-&gt;manager-&gt;staff</code></li>
490 </ul></li>
491 </ul>
492
493 </div>
494
495 <div class="slide">
496 <h1>Conventional Delegates (cont.)</h1>
497
498 <pre><code>
499 has phone => (
500     ...
501     handles => [qw(number extension)],
502 );
503 </code></pre>
504
505 </div>
506
507 <div class="slide">
508 <h1>Conventional Delegates (cont.)</h1>
509
510 <pre><code>
511 has phone => (
512     ...
513     isa     => "Phone",
514     handles => qr/^[a-z]w+$/,
515 );
516 </code></pre>
517
518 </div>
519
520 <div class="slide">
521 <h1>Conventional Delegates (cont.)</h1>
522
523 <pre><code>
524 has phone => (
525     ...
526     handles => "Dialing", # a role
527 );
528 </code></pre>
529
530 </div>
531
532 <div class="slide">
533 <h1>UnConventional Delegates</h1>
534
535 <pre><code>
536 package Company;
537 use Moose;
538 use MooseX::AttributeHelpers;
539
540 has employees => (
541     metaclass => 'Collection::Array',
542     isa => 'ArrayRef[Employees]',
543     is  => 'rw',
544     provides => {
545         push  => 'add_employee',
546         pop   => 'remove_employee',
547         count => 'number_of_employees',
548         empty => 'any_employees',
549     },
550 );
551 </code></pre>
552
553 </div>
554
555 <div class="slide">
556 <h1>Modified Methods</h1>
557
558 <pre><code>
559 before 'employees' => sub { warn 'calling employees' };
560
561 after 'employees' => sub { warn 'finished calling employees' };
562 </code></pre>
563
564 <ul>
565 <li>Pre/Post hooks
566 <ul>
567 <li>Get a copy of <code>@_</code></li>
568 <li>Return value is ignored</li>
569 </ul></li>
570 </ul>
571
572 </div>
573
574 <div class="slide">
575 <h1>Modified Methods (cont.)</h1>
576
577 <pre><code>
578 around 'employees' => sub { 
579     my ($next, $self, @args) = @_;
580     ...
581     my @return = $self->$next(@args);
582     ...
583     return @return;
584 };
585 </code></pre>
586
587 </div>
588
589 <div class="slide">
590 <h1>Modified Methods (cont.)</h1>
591
592 <pre><code>
593 package Employee;
594 use Moose;
595
596 sub do_work {
597     my $self = shift;
598
599     $self->punch_in;
600
601     inner(); # call subclass here
602
603     $self->punch_out;
604 }
605 </code></pre>
606
607 </div>
608
609 <div class="slide">
610 <h1>Modified Methods (cont.)</h1>
611
612 <pre><code>
613 package Employee::Chef;
614 use Moose;
615
616 extends qw(Employee);
617
618 augment do_work => sub {
619     my $self = shift;
620
621     while ( @burgers ) {
622         $self->flip_burger(shift @burgers);
623     }
624 };
625
626 $chef->do_work; # punch in, flip burgers, punch out
627 </code></pre>
628
629 </div>
630
631 <div class="slide">
632 <h1>Some Type of Coercion</h1>
633
634 <pre><code>
635 package Employee;
636 use Moose;
637 use Moose::Util::TypeConstraints;
638 extends qw(Person);
639
640 class_type 'Manager';
641
642 coerce 'Manager' => (
643     from 'Str' => via { Manager->new( name => $_ ) },
644 );
645
646 has manager => (
647     is => 'ro',
648     isa => 'Manager',
649     required => 1, 
650     coerce => 1,
651 );
652 </code></pre>
653
654 </div>
655
656 <div class="slide">
657 <h1>Some Type of Coercion (cont.)</h1>
658
659 <pre><code>
660 # import type constraint keywords
661 use Moose::Util::TypeConstraints;
662
663
664 # define Manager, a subtype of Object
665 class_type "Manager";
666
667
668 # define the conversion
669 ... via { Manager->new( name => $_ ) }
670
671
672 # enable it per attribute
673 has manager => (
674     ...
675     coerce => 1,
676 );
677 </code></pre>
678
679 <div class="notes">
680 <p>breakdown of the example</p>
681
682 <p>class types are automatically created for all Moose classes</p>
683 </div>
684 </div>
685
686 <div class="slide">
687 <h1>Some Type of Digression</h1>
688
689 <pre><code>
690 has employees => (
691     is => 'rw',
692     isa => 'ArrayRef[Employee]',
693 );
694
695 has shopping_carts => (
696     is => 'rw',
697     isa => 'ArrayRef[ArrayRef[ShinyBead]]'
698 );
699 </code></pre>
700
701 <div class="notes">
702 <p>Going to go into features of the type system for a bit</p>
703
704 <p>Parametrized types</p>
705 </div>
706 </div>
707
708 <div class="slide">
709 <h1>Some Type of Digression (cont.)</h1>
710
711 <pre><code>
712 has language => (
713     is => 'rw',
714     isa => 'English | Welsh | Scots | Gaelic',
715 );  
716
717 has member => (
718     is => 'rw',
719     isa => 'Employee | ArrayRef[ Employee | Group ]',
720 );
721 </code></pre>
722
723 <div class="notes">
724 <p>Union types</p>
725 </div>
726 </div>
727
728 <div class="slide">
729 <h1>Some Type of Digression (cont.)</h1>
730
731 <pre><code>
732 package Foo;
733 use Moose;
734 use Moose::Util::TypeConstraints;
735
736 use Test::Deep qw(eq_deeply ...);
737
738 type 'SomethingTricky' => where {
739     eq_deeply( $_, ... );
740 };
741
742 has 'bar' => (
743     is  => 'rw',
744     isa => 'SomethingTricky',
745 );
746 </code></pre>
747
748 <div class="notes">
749 <p>Test::Deep custom validator</p>
750
751 <p>Can use any validation from the CPAN</p>
752 </div>
753 </div>
754
755 <div class="slide">
756 <h1>Some Parametrized Type of Coercion</h1>
757
758 <pre><code>
759 use Moose::Util::TypeConstraints;
760
761 subtype 'ArrayRef[Employee]' => as 'ArrayRef';
762
763 coerce 'ArrayRef[Employee]' => (
764     from 'ArrayRef[Str]' via {
765         [ map { Employee->new( name => $_ ) } @$_ ]
766     },
767 );
768
769 has staff => (
770     isa    => 'ArrayRef[Employee]',
771     coerce => 1,
772 );
773 </code></pre>
774
775 <div class="notes">
776 <p>coerce parametrized ArrayRef[Employee] from ArrayRef[Str]</p>
777 </div>
778 </div>
779
780 <div class="slide">
781 <h1>Role of the Moose </h1>
782
783 <ul>
784 <li>A role is like a…
785 <ul>
786 <li>Java Interface: safe</li>
787 <li>mixin: useful</li>
788 </ul></li>
789 <li>A role is for small reusable behaviors
790 <ul>
791 <li>better than using a multiple inheritence</li>
792 </ul></li>
793 </ul>
794
795 </div>
796
797 <div class="slide">
798 <h1>Role of the Moose (cont.)</h1>
799
800 <ul>
801 <li>Roles on the CPAN:
802 <ul>
803 <li><code>MooseX::Clone</code> - Flexible <code>clone</code> method</li>
804 <li><code>MooseX::Storage</code> - Flexible serialization</li>
805 <li><code>MooseX::Getopt</code> - <code>@ARGV</code> aware constructor</li>
806 <li><code>MooseX::LogDispatch</code> - <code>$self-&gt;logger-&gt;info("something happenned")</code></li>
807 <li><code>MooseX::Param</code> - <code>param</code> method like <code>CGI.pm</code>&#8217;s,</li>
808 </ul></li>
809 </ul>
810
811 <div class="notes">
812 <p>Some examples of small reusable behaviors</p>
813
814 <p>Param is good for interacting with e.g. CGI::Expand or similar modules</p>
815 </div>
816 </div>
817
818 <div class="slide">
819 <h1>Role of the Moose (cont.)</h1>
820
821 <pre><code>
822 package Minion;
823 use Moose;
824
825 extends qw(Employee);
826
827 with qw(Salaried::Hourly);
828
829
830 package Boss;
831 use Moose;
832
833 extends qw(Employee);
834
835 with qw(Salaried::Monthly);
836
837 </code></pre>
838
839 <ul>
840 <li><code>with</code> adds roles into your class
841 <ul>
842 <li><code>Salaried::Hourly</code> was added to <code>Minion</code></li>
843 </ul></li>
844 </ul>
845
846 </div>
847
848 <div class="slide">
849 <h1>Role of the Moose (cont.)</h1>
850
851 <pre><code>
852 package Salaried;
853 use Moose::Role;
854
855 requires 'paycheck_amount';
856 </code></pre>
857
858 <ul>
859 <li>Just an interface</li>
860 </ul>
861
862 </div>
863
864 <div class="slide">
865 <h1>Role of the Moose (cont.)</h1>
866
867 <pre><code>
868 package Salaried::Hourly;
869 use Moose::Role;
870
871 with qw(Salaried);
872
873 has hourly_rate => (
874     isa => "Num",
875     is  => "rw",
876     required => 1,
877 );
878
879 has logged_hours => (
880     isa => "Num",
881     is  => "rw",
882     default => 0,
883 );
884
885 # satisfy the Salaried interface:
886 sub paycheck_amount {
887     my $self = shift;
888     $self->logged_hours * $self->hourly_rate;
889 }
890
891 </code></pre>
892
893 <ul>
894 <li>More than an interface</li>
895 </ul>
896
897 </div>
898
899 <div class="slide">
900 <h1>Role of the Moose (cont.)</h1>
901
902 <ul>
903 <li>More than Java Interfaces
904 <ul>
905 <li>Interfaces are behavior &#8220;contracts&#8221;</li>
906 <li>Roles can also have code</li>
907 </ul></li>
908 </ul>
909
910 <div class="notes">
911 <p>roles can have attributes and methods
912 roles provide behavior, not just interface</p>
913 </div>
914 </div>
915
916 <div class="slide">
917 <h1>Role of the Moose (cont.)</h1>
918
919 <ul>
920 <li>Role Composition
921 <ul>
922 <li>Not inheritence</li>
923 <li>Symmetric</li>
924 <li>Unordered</li>
925 </ul></li>
926 </ul>
927
928 </div>
929
930 <div class="slide">
931 <h1>Role of the Moose (cont.)</h1>
932
933 <ul>
934 <li>Role Composition
935 <ul>
936 <li>Less ambiguity</li>
937 <li>Compile time errors</li>
938 <li>…And ways to fix them</li>
939 </ul></li>
940 </ul>
941
942 <div class="notes">
943 <p>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
944 multiple inheritence silently assumes you want the first class</p>
945
946 <p>roles cause errors at compile time, unlike multiple inheritence</p>
947
948 <p>roles also provide easy ways to fix the errors</p>
949 </div>
950 </div>
951
952 <div class="slide">
953 <h1>Role of the Moose (cont.)</h1>
954
955 <pre><code>
956 package Ballet;
957 use Moose::Role;
958
959 sub dance {
960     pirouette();
961 }
962
963 package Punk;
964 use Moose::Role
965
966 sub dance {
967     MOSH!!!11one();
968 }
969
970 package Foo;
971 use Moose;
972
973 # KABOOM:
974 with qw(
975     Punk
976     Ballet
977 );
978 </code></pre>
979
980 <div class="notes">
981 <p>conflicts</p>
982 </div>
983 </div>
984
985 <div class="slide">
986 <h1>Role of the Moose (cont.)</h1>
987
988 <pre><code>
989 package Ent::Puppy;
990 use Moose;
991
992 with (
993     Tree => {
994         alias => {
995             bark => "tree_bark",
996         },
997     },
998     Dog => {
999         alias => {
1000             bark => "bark_sound",
1001         }
1002     },
1003 );
1004
1005 sub bark {
1006     my $self = shift;
1007
1008     if ( $condition ) {
1009         $self->tree_bark;
1010     } else {
1011         $self->bark_sound;
1012     }
1013 }
1014 </code></pre>
1015
1016 <ul>
1017 <li>Not that common in practice</li>
1018 </ul>
1019
1020 <div class="notes">
1021 <p>Composition parameters
1022 Easier conflict resolution
1023 Finer grained control</p>
1024 </div>
1025 </div>
1026
1027 <div class="slide">
1028 <h1>MOPs Mean Cleanliness</h1>
1029
1030 <ul>
1031 <li>Moose is based on <code>Class::MOP</code>
1032 <ul>
1033 <li>Metaobject Protocol for Perl 5</li>
1034 <li>&#8220;makes an object for everything&#8221;</li>
1035 </ul></li>
1036 </ul>
1037
1038 <pre><code>
1039 my $class = $obj->meta;       # $obj's metaclass
1040 my $meta  = MyApp->meta;      # MyApp's metaclass
1041 my $emo   = $obj->meta->meta; # even more meta!
1042
1043 warn  $obj->meta->name;
1044 </code></pre>
1045
1046 </div>
1047
1048 <div class="slide">
1049 <h1>Looking in From the Inside</h1>
1050
1051 <pre><code>
1052 my $metaclass = $self->meta; 
1053
1054 $metaclass->superclasses;
1055
1056 $metaclass->linearized_isa;
1057
1058 $metaclass->has_method("foo");
1059
1060 $metaclass->compute_all_applicable_attributes;
1061
1062 # … lots more
1063 </code></pre>
1064
1065 <div class="notes">
1066 <p>simple introspection</p>
1067 </div>
1068 </div>
1069
1070 <div class="slide">
1071 <h1>Looking in From the Inside (cont.)</h1>
1072
1073 <pre><code>
1074 Moose::Meta::Class->create( Bar =>
1075       version      => '0.01',
1076       superclasses => [ 'Foo' ],
1077       attributes => [
1078           Moose::Meta::Attribute->new( bar => ... ),
1079           Moose::Meta::Attribute->new( baz => ... ),
1080       ],
1081       methods => {
1082           calculate_bar => sub { ... },
1083           construct_baz => sub { ... }
1084       },
1085 );
1086
1087 my $anon_meta = Moose::Meta::Class->create_anon_class( ... );
1088 </code></pre>
1089
1090 <div class="notes">
1091 <p>Classes can be created programmatically</p>
1092 </div>
1093 </div>
1094
1095 <div class="slide">
1096 <h1>Looking in From the Inside (cont.)</h1>
1097
1098 <pre><code>
1099 has foo => ( is => "rw" );
1100
1101 __PACKAGE__->meta->add_attribute(
1102     "foo",  
1103     is => "rw",
1104 );
1105 </code></pre>
1106
1107 <ul>
1108 <li>Moose is just sugar
1109 <ul>
1110 <li>The MOP does the hard work</li>
1111 </ul></li>
1112 </ul>
1113
1114 </div>
1115
1116 <div class="slide">
1117 <h1>The Metaclass Tango</h1>
1118
1119 <ul>
1120 <li>Metaclassses control class behavior</li>
1121 </ul>
1122
1123 <pre><code>
1124 has employees => (
1125     metaclass => 'Collection::Array',
1126     ...
1127 );
1128 </code></pre>
1129
1130 <ul>
1131 <li>custom attribute metaclasses
1132 <ul>
1133 <li>change how attributes work</li>
1134 </ul></li>
1135 <li>Many customizable parts
1136 <ul>
1137 <li><code>Moose::Meta::Class</code>, <code>Moose::Meta::Attribute,</code><code>Moose::Meta::Method</code>, <code>Moose::Meta::Method::Accessor</code> <code>Moose::Meta::Instance</code>, <code>Moose::Meta::Role</code>, <code>Moose::Meta::TypeConstraint</code>, …,</li>
1138 </ul></li>
1139 </ul>
1140
1141 </div>
1142
1143 <div class="slide">
1144 <h1>Working in the Meta Frame</h1>
1145
1146 <ul>
1147 <li><code>$work</code> project:</li>
1148 <li>CMS for a flash website</li>
1149 <li>Content is in XML</li>
1150 </ul>
1151
1152 </div>
1153
1154 <div class="slide">
1155 <h1>Working in the Meta Frame (cont.)</h1>
1156
1157 <ul>
1158 <li>Step 1. use Moose</li>
1159 <li>Step 2. ???</li>
1160 <li>Step 3. Profit!</li>
1161 </ul>
1162
1163 </div>
1164
1165 <div class="slide">
1166 <h1>Working in the Meta Frame (cont.)</h1>
1167
1168 <ul>
1169 <li>Step 2.1. Client&#8217;s XML schemas → Moose classes
1170 <ul>
1171 <li>Automatic class definitions</li>
1172 <li>High level objects in runtime</li>
1173 <li>XML storage backed
1174 <ul>
1175 <li>SAX → Moose</li>
1176 <li>Moose → SAX</li>
1177 </ul></li>
1178 </ul></li>
1179 </ul>
1180
1181 </div>
1182
1183 <div class="slide">
1184 <h1>Working in the Meta Frame (cont.)</h1>
1185
1186 <ul>
1187 <li>Step 2.2. Meta descriptions
1188 <ul>
1189 <li>Extend the metaclasses</li>
1190 <li>Embed additional information
1191 <ul>
1192 <li>field types</li>
1193 <li>access control</li>
1194 </ul></li>
1195 </ul></li>
1196 </ul>
1197
1198 </div>
1199
1200 <div class="slide">
1201 <h1>Working in the Meta Frame (cont.)</h1>
1202
1203 <ul>
1204 <li>Step 2.3 Introspection goodness
1205 <ul>
1206 <li>Generic web frontend</li>
1207 <li>Object introspection based
1208 <ul>
1209 <li>HTML view</li>
1210 <li>Editing widgets</li>
1211 </ul></li>
1212 <li>Clean, extensible</li>
1213 </ul></li>
1214 </ul>
1215
1216 </div>
1217
1218 <div class="slide">
1219 <h1>Drawbacks of Moose</h1>
1220
1221 <ul>
1222 <li>Load time
1223 <ul>
1224 <li><code>MooseX::Compile</code> is in the works</li>
1225 </ul></li>
1226 <li>Some features are slow
1227 <ul>
1228 <li>but you only pay for what you use</li>
1229 </ul></li>
1230 <li>Extending non-Hash based classes is tricky.
1231 <ul>
1232 <li>but possible: <code>MooseX::GlobRef::Object</code></li>
1233 </ul></li>
1234 </ul>
1235
1236 </div>
1237
1238 <div class="slide">
1239 <h1>Benefits of Moose</h1>
1240
1241 <ul>
1242 <li>Less boilerplate
1243 <ul>
1244 <li>attribute storage/access</li>
1245 <li>construction</li>
1246 <li>destruction</li>
1247 <li>verification</li>
1248 <li>…</li>
1249 </ul></li>
1250 </ul>
1251
1252 </div>
1253
1254 <div class="slide">
1255 <h1>Benefits of Moose (cont.)</h1>
1256
1257 <ul>
1258 <li>Shorter
1259 <ul>
1260 <li>less reading</li>
1261 <li>less writing</li>
1262 <li>less code means fewer bugs</li>
1263 </ul></li>
1264 </ul>
1265
1266 </div>
1267
1268 <div class="slide">
1269 <h1>Benefits of Moose (cont.)</h1>
1270
1271 <ul>
1272 <li>Less testing
1273 <ul>
1274 <li>Moose is very well tested
1275 <ul>
1276 <li>no need to check accessor behavior, etc</li>
1277 </ul></li>
1278 <li>focus on your code&#8217;s purpose
1279 <ul>
1280 <li>not that it is &#8220;assembled&#8221; correctly</li>
1281 <li>http://c2.com/cgi/wiki?IntentionNotAlgorithm</li>
1282 </ul></li>
1283 </ul></li>
1284 </ul>
1285
1286 </div>
1287
1288 <div class="slide">
1289 <h1>Benefits of Moose (cont.)</h1>
1290
1291 <ul>
1292 <li>More readable
1293 <ul>
1294 <li>declarative style is self documenting</li>
1295 <li>good signal to noise ratio</li>
1296 </ul></li>
1297 </ul>
1298
1299 </div>
1300
1301 <div class="slide">
1302 <h1>Benefits of Moose (cont.)</h1>
1303
1304 <ul>
1305 <li>Meta object protocol
1306 <ul>
1307 <li>Cleans up Perl&#8217;s OO</li>
1308 <li>Provides introspection</li>
1309 <li>Enables powerful abstractions</li>
1310 </ul></li>
1311 </ul>
1312
1313 </div>
1314
1315 <div class="slide">
1316 <h1>Benefits of Moose (cont.)</h1>
1317
1318 <ul>
1319 <li>It&#8217;s the new black
1320 <ul>
1321 <li>All the cool kids hang out on #moose</li>
1322 <li>Smart sounding buzzwords</li>
1323 <li>Chicks dig antlers</li>
1324 <li>Ruby is so 2007</li>
1325 </ul></li>
1326 </ul>
1327
1328 </div>
1329
1330 <div class="slide">
1331 <h1>Bonus Material</h1>
1332
1333 </div>
1334
1335 <div class="slide">
1336 <h1>Autobox</h1>
1337
1338 <pre><code>
1339 package Units::Bytes;
1340 use Moose::Role;
1341 use Moose::Autobox;
1342
1343 sub bytes     { $_[0]                   }
1344 sub kilobytes { $_[0] * 1024            }
1345 sub megabytes { $_[0] * 1024->kilobytes }
1346 sub gigabytes { $_[0] * 1024->megabytes }
1347 sub terabytes { $_[0] * 1024->gigabytes }
1348
1349 Moose::Autobox->mixin_additional_role(
1350     SCALAR => 'Units::Bytes',
1351 );
1352 </code></pre>
1353
1354 </div>
1355
1356 <div class="slide">
1357 <h1>Autobox (cont.)</h1>
1358
1359 <pre><code>
1360 use Units::Bytes;
1361 use Moose::Autobox; # autoboxing is lexical
1362
1363 is(5->bytes,     5,             '... got 5 bytes');
1364 is(5->kilobytes, 5120,          '... got 5 kilobytes');
1365 is(2->megabytes, 2097152,       '... got 2 megabytes');
1366 is(1->gigabytes, 1073741824,    '... got 1 gigabyte');
1367 is(2->terabytes, 2199023255552, '... got 2 terabytes');
1368 </code></pre>
1369
1370 </div>
1371
1372 <div class="slide">
1373 <h1>perl -Moose</h1>
1374
1375 <ul>
1376 <li>Moose One Liners with <code>oose.pm</code></li>
1377 </ul>
1378
1379 <pre><code>
1380 perl -Moose -e 'has foo => ( is=> "rw" ); Class->new( foo => 1 )'
1381 </code></pre>
1382
1383 <ul>
1384 <li>Useful for testing if something works</li>
1385 <li>Helpful on IRC</li>
1386 <li><code>Devel::REPL</code> is cooler though ;-)</li>
1387 </ul>
1388
1389 </div>
1390
1391 <div class="slide">
1392 <h1>MooseX::POE</h1>
1393
1394 <pre><code>
1395 package Counter;
1396 use MooseX::POE;
1397 use MooseX::AttributeHelpers;
1398
1399 has count => (
1400     metaclass => 'Counter',
1401     provides => { inc => "increment_count" },
1402 );
1403
1404 sub START {
1405     shift->yield('increment');
1406 }
1407
1408 event increment => sub {
1409     my $self = shift;
1410
1411     warn "Count is now " . $self->count;
1412
1413     $self->increment_count;
1414     $self->yield('increment') unless $self->count > 3;
1415 };
1416
1417 Counter->new( count => 0 );
1418 POE::Kernel->run();
1419 </code></pre>
1420
1421 <ul>
1422 <li>PoCos made easy</li>
1423 <li>Every object has a <code>POE::Session</code></li>
1424 <li><code>event</code> declares POE object states</li>
1425 </ul>
1426
1427 </div>
1428
1429 <div class="slide">
1430 <h1>Fin</h1>
1431
1432 <ul>
1433 <li><p>Slides written by:</p>
1434
1435 <ul>
1436 <li>Chris Prather</li>
1437 <li>Stevan Little</li>
1438 <li>Robert Boone</li>
1439 </ul></li>
1440 <li><p>Slides deleted by:</p>
1441
1442 <ul>
1443 <li>Yuval Kogman</li>
1444 </ul></li>
1445 </ul>
1446
1447 </div>
1448
1449
1450 </div>
1451
1452 </body>
1453 </html>