Added CC license
[gitmo/moose-presentations.git] / moose-class / slides / index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
5
6 <head>
7 <title>Introduction to Moose</title>
8 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
9 <!-- metadata -->
10 <meta name="generator" content="S5" />
11 <meta name="version" content="S5 1.2a2" />
12 <meta name="author" content="Eric A. Meyer" />
13 <meta name="company" content="Complex Spiral Consulting" />
14 <!-- configuration parameters -->
15 <meta name="defaultView" content="slideshow" />
16 <meta name="controlVis" content="hidden" />
17 <!-- style sheet links -->
18 <link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
19 <link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
20 <link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
21 <link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
22 <!-- embedded styles -->
23 <style type="text/css" media="all">
24 .imgcon {width: 525px; margin: 0 auto; padding: 0; text-align: center;}
25 #anim {width: 270px; height: 320px; position: relative; margin-top: 0.5em;}
26 #anim img {position: absolute; top: 42px; left: 24px;}
27 img#me01 {top: 0; left: 0;}
28 img#me02 {left: 23px;}
29 img#me04 {top: 44px;}
30 img#me05 {top: 43px;left: 36px;}
31 </style>
32 <!-- S5 JS -->
33 <script src="ui/default/slides.js" type="text/javascript"></script>
34 <link rel="stylesheet" href="ui/custom.css" type="text/css" />
35 </head>
36 <body>
37
38 <div class="layout">
39 <div id="controls"><!-- DO NOT EDIT --></div>
40 <div id="currentSlide"><!-- DO NOT EDIT --></div>
41 <div id="header"></div>
42 <div id="footer">
43   <div id="license">
44     <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png" /></a>
45     <br /><span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" property="dc:title" rel="dc:type">Intro to Moose Class</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">David Rolsky</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/us/">Creative Commons Attribution-Share Alike 3.0 United States License</a>.
46   </div>
47
48   <h2>Introduction to Moose</h2>
49 </div>
50 </div>
51
52 <div class="presentation">
53
54 <div class="slide">
55   <h1>Introduction to Moose</h1>
56   <h2>YAPC 2009</h2>
57 </div>
58
59 <div class="slide">
60   <h1>Moose Summed Up</h1>
61
62   <ul>
63     <li><strong>Declarative</strong> OO sugar</li>
64     <li>Introspectable</li>
65     <li>Extensible</li>
66   </ul>
67 </div>
68
69 <div class="slide">
70   <h1>Moose Background</h1>
71
72   <ul>
73     <li>Created by Stevan Little, first released in 2006</li>
74     <li>Moose builds on Perl 5's native OO</li>
75     <li>Borrows ideas from other languages, notably Perl 6</li>
76     <li>Provides semantics for common operations</li>
77   </ul>
78 </div>
79
80 <div class="slide fake-slide0">
81   <h1>Part 0: Moose Concepts</h1>
82 </div>
83
84 <div class="slide">
85   <h1>Classes</h1>
86
87   <ul>
88     <li>
89       Classes have ...
90       <ul>
91         <li>Attributes</li>
92         <li>Methods</li>
93         <li>Superclasses</li>
94         <li>Method modifiers</li>
95         <li>Constructor and destructor</li>
96         <li>One metaclass object</li>
97       </ul>
98     </li>
99     <li>Classes do roles</li>
100   </ul>
101 </div>
102
103 <div class="slide">
104   <h1>Class Example</h1>
105
106   <pre><code>package Person;
107 <span class="highlight">use Moose;</span></code></pre>
108
109   <ul>
110     <li>Poof, a Moose-based class!</li>
111   </ul>
112 </div>
113
114 <div class="slide">
115   <h1>Attributes</h1>
116
117   <ul>
118     <li>Aka property, slot, field, member variable</li>
119     <li>A piece of data owned by an object</li>
120   </ul>
121 </div>
122
123 <div class="slide">
124   <h1>Attributes</h1>
125
126   <ul>
127     <li>
128       Attributes have ...
129       <ul>
130         <li>Access-control (read-only vs read-write)</li>
131         <li>An optional type</li>
132         <li>Accessor methods</li>
133         <li>Delegation methods</li>
134         <li>Optional default value</li>
135         <li>Many more features</li>
136       </ul>
137     </li>
138     <li>Stored in the object, but don't worry about that</li>
139   </ul>
140 </div>
141
142 <div class="slide">
143   <h1>Attribute Example</h1>
144
145   <pre><code>package Person;
146 use Moose;
147
148 <span class="highlight">has first_name =&gt; ( is =&gt; 'rw' );</span></code></pre>
149
150 </div>
151
152 <div class="slide">
153   <h1>Methods</h1>
154
155   <ul>
156     <li>Nothing fancy here, just Perl subroutines</li>
157   </ul>
158
159   <pre><code>package Person;
160 use Moose;
161
162 <span class="highlight">sub greet { ... }</span></code></pre>
163 </div>
164
165 <div class="slide">
166   <h1>Roles</h1>
167
168   <ul>
169     <li>Classes <strong>do</strong> (or consume) roles</li>
170     <li>Similar to mixins and Java interfaces</li>
171   </ul>
172 </div>
173
174 <div class="slide">
175   <h1>Roles</h1>
176
177   <ul>
178     <li>Like classes, can have attributes, methods, do roles</li>
179     <li>Roles can require methods</li>
180     <li>Roles are composed (flattened) into classes</li>
181   </ul>
182 </div>
183
184 <div class="slide">
185   <h1>Role Example</h1>
186
187 <pre><code>package HasPermissions;
188 <span class="highlight">use Moose::Role;</span>
189
190 has is_admin =&gt; ( is =&gt; 'rw' );</code></pre>
191 </div>
192
193 <div class="slide">
194   <h1>Role Example</h1>
195
196   <p>
197     And then ...
198   </p>
199   
200 <pre><code>package Person;
201 use Moose;
202
203 <span class="highlight">with 'HasPermissions';</span></code></pre>
204 </div>
205
206 <div class="slide">
207   <h1>Method Modifiers</h1>
208
209   <ul>
210     <li>AKA advice</li>
211     <li>&quot;<strong>Before</strong> foo(), do this first&quot;</li>
212     <li>&quot;Do this <strong>after</strong> foo()</li>
213     <li>&quot;Put this code <strong>around</strong> foo()&quot;</li>
214   </ul>
215 </div>
216
217 <div class="slide">
218   <h1>Before &amp; After</h1>
219
220 <pre><code>before 'foo'
221     =&gt; sub { warn 'About to call foo()' };
222
223 after  'foo'
224     =&gt; sub { warn 'Leaving foo()' };</code></pre>
225
226 </div>
227
228 <div class="slide">
229   <h1>Around</h1>
230
231 <pre><code>around 'foo' =&gt; sub {
232     my $real_foo = shift;
233     my $self     = shift;
234
235     warn 'Just before foo()';
236     my @return =
237         $self-&gt;$real_foo( @_, bar =&gt; 42 );
238
239     return ( @return, 'modify return values' );
240 };</code></pre>
241 </div>
242
243 <div class="slide">
244   <h1>Type Constraints</h1>
245
246   <ul>
247     <li>NOT A FULL-BLOWN TYPE SYSTEM!</li>
248     <li>But still darn useful</li>
249     <li>Constrain attribute values</li>
250     <li>Coerce from other types</li>
251   </ul>
252 </div>
253
254 <div class="slide">
255   <h1>Type Constraint Example</h1>
256
257 <pre><code>package Person;
258 use Moose;
259
260 has weight =&gt; (
261     is  =&gt; 'ro',
262     <span class="highlight">isa =&gt; 'Int'</span>,
263 );
264
265 # kaboom
266 Person-&gt;new( weight =&gt; 'fat' );</code></pre>
267 </div>
268
269 <div class="slide">
270   <h1>Delegation</h1>
271
272   <ul>
273     <li>Attributes can define delegations</li>
274     <li>Lets you hide some implementation details</li>
275     <li>Fewer objects to chase around</li>
276   </ul>
277 </div>
278
279 <div class="slide">
280   <h1>Delegation</h1>
281
282 <pre><code>package Person;
283 use Moose;
284
285 has blog_uri =&gt; (
286     is      =&gt; 'rw',
287     isa     =&gt; 'URI',
288     <span class="highlight">handles =&gt; { 'blog_hostname' =&gt; 'host' },</span>
289 );
290
291 <span class="highlight">$person->blog_hostname;</span>
292 # really calls $person->blog_uri->host</code></pre>
293 </div>
294
295 <div class="slide">
296   <h1>Constructors</h1>
297
298   <ul>
299     <li>Moose creates <code>new()</code> for you</li>
300     <li>Provide an optional <code>BUILDARGS()</code> and <code>BUILD()</code></li>
301   </ul>
302 </div>
303
304 <div class="slide">
305   <h1>Destructors</h1>
306
307   <ul>
308     <li>Provide an optional <code>DEMOLISH()</code></li>
309   </ul>
310 </div>
311
312 <div class="slide">
313   <h1>Moose Meta-API</h1>
314
315   <ul>
316     <li>Answers questions like ...
317       <ul>
318         <li>What methods does this class have?</li>
319         <li>What are its parents?</li>
320         <li>What attributes does it have (including inherited attributes)?</li>
321         <li>What roles does it do?</li>
322         <li>Much, much, more</li>
323       </ul>
324     </li>
325   </ul>
326 </div>
327
328 <div class="slide">
329   <h1>Moose Meta-API</h1>
330
331   <ul>
332     <li>Not just for introspection ...
333       <ul>
334         <li>Add methods, attributes, roles, etc</li>
335         <li>Extend and alter core features</li>
336       </ul>
337     </li>
338   </ul>
339 </div>
340
341 <div class="slide">
342   <h1>Why Moose?</h1>
343
344   <ul>
345     <li>A quick bit of propoganda ...</li>
346   </ul>
347 </div>
348
349 <div class="slide">
350   <h1>With Moose</h1>
351
352   <pre><code>package Person;
353 use Moose;
354
355 has last_name =&gt; (
356     is  =&gt; 'rw',
357     isa =&gt; 'Str',
358 );</code></pre>
359 </div>
360
361 <div class="slide">
362     <h1>Without Moose</h1>
363
364     <pre class="small"><code>package Person;
365 use strict;
366 use warnings;
367 use Carp 'confess';
368
369 sub new {
370     my $class = shift;
371     my %args  = @_;
372     my $self  = {};
373
374     if (exists $args{last_name}) {
375         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
376                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
377             if ref($args{last_name});
378         $self-&gt;{last_nane} = $args{last_name};
379     }
380
381     return bless $self, $class;
382 }
383
384 sub last_name {
385     my $self = shift;
386
387     if (@_) {
388         my $value = shift;
389         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
390                 . &quot;Validation failed for 'Str' with value $value&quot;
391             if ref($value);
392         $self-&gt;{last_name} = $value;
393     }
394
395     return $self-&gt;{last_name};
396 }</code></pre>
397
398 </div>
399
400 <div class="slide">
401     <h1>Side by side</h1>
402
403     <table class="side-by-side">
404         <tr>
405           <td>
406             <pre><code>package Person;
407 use Moose;
408
409 has last_name =&gt; (
410     is  =&gt; 'rw',
411     isa =&gt; 'Str',
412 );</code></pre>
413             </td>
414             <td>
415                 <pre class="small"><code>package Person;
416 use strict;
417 use warnings;
418 use Carp 'confess';
419
420 sub new {
421     my $class = shift;
422     my %args  = @_;
423     my $self  = {};
424
425     if (exists $args{last_name}) {
426         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
427                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
428             if ref($args{last_name});
429         $self-&gt;{last_nane} = $args{last_name};
430     }
431
432     return bless $self, $class;
433 }
434
435 sub last_name {
436     my $self = shift;
437
438     if (@_) {
439         my $value = shift;
440         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
441                 . &quot;Validation failed for 'Str' with value $value&quot;
442             if ref($value);
443         $self-&gt;{last_name} = $value;
444     }
445
446     return $self-&gt;{last_name};
447 }</code></pre>
448             </td>
449         </tr>
450     </table>
451
452 </div>
453
454 <div class="slide">
455     <h1>Side by side</h1>
456
457     <table class="side-by-side">
458         <tr>
459             <td>
460                 <pre><code><span class="match-moose">package Person;</span>
461 use Moose;
462
463 has last_name =&gt; (
464     is  =&gt; 'rw',
465     isa =&gt; 'Str',
466 );</code></pre>
467             </td>
468             <td>
469                 <pre class="small"><code><span class="match-unsweet">package Person;</span>
470 use strict;
471 use warnings;
472 use Carp 'confess';
473
474 sub new {
475     my $class = shift;
476     my %args  = @_;
477     my $self  = {};
478
479     if (exists $args{last_name}) {
480         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
481                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
482             if ref($args{last_name});
483         $self-&gt;{last_nane} = $args{last_name};
484     }
485
486     return bless $self, $class;
487 }
488
489 sub last_name {
490     my $self = shift;
491
492     if (@_) {
493         my $value = shift;
494         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
495                 . &quot;Validation failed for 'Str' with value $value&quot;
496             if ref($value);
497         $self-&gt;{last_name} = $value;
498     }
499
500     return $self-&gt;{last_name};
501 }</code></pre>
502             </td>
503         </tr>
504     </table>
505 </div>
506
507 <div class="slide">
508     <h1>Side by side</h1>
509
510     <table class="side-by-side">
511         <tr>
512             <td>
513                 <pre><code>package Person;
514 <span class="match-moose">use Moose;</span>
515
516 has last_name =&gt; (
517     is  =&gt; 'rw',
518     isa =&gt; 'Str',
519 );</code></pre>
520             </td>
521             <td>
522                 <pre class="small"><code>package Person;
523 <span class="match-unsweet">use strict;
524 use warnings;
525 use Carp 'confess';
526
527 sub new {
528     my $class = shift;
529     my %args  = @_;
530     my $self  = {};</span>
531
532     if (exists $args{last_name}) {
533         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
534                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
535             if ref($args{last_name});
536         $self-&gt;{last_nane} = $args{last_name};
537     }
538
539     <span class="match-unsweet">return bless $self, $class;
540 }</span>
541
542 sub last_name {
543     my $self = shift;
544
545     if (@_) {
546         my $value = shift;
547         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
548                 . &quot;Validation failed for 'Str' with value $value&quot;
549             if ref($value);
550         $self-&gt;{last_name} = $value;
551     }
552
553     return $self-&gt;{last_name};
554 }</code></pre>
555             </td>
556         </tr>
557     </table>
558 </div>
559
560 <div class="slide">
561     <h1>Side by side</h1>
562
563     <table class="side-by-side">
564         <tr>
565             <td>
566                 <pre><code>package Person;
567 use Moose;
568
569 <span class="match-moose">has last_name =&gt; (</span>
570     is  =&gt; 'rw',
571     isa =&gt; 'Str',
572 <span class="match-moose">);</span></code></pre>
573             </td>
574             <td>
575                 <pre class="small"><code>package Person;
576 use strict;
577 use warnings;
578 use Carp 'confess';
579
580 sub new {
581     my $class = shift;
582     my %args  = @_;
583     my $self  = {};
584
585     <span class="match-unsweet">if (exists $args{last_name}) {</span>
586         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
587                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
588             if ref($args{last_name});
589         <span class="match-unsweet">$self-&gt;{last_nane} = $args{last_name};
590     }</span>
591
592     return bless $self, $class;
593 }
594
595 sub last_name {
596     my $self = shift;
597
598     if (@_) {
599         my $value = shift;
600         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
601                 . &quot;Validation failed for 'Str' with value $value&quot;
602             if ref($value);
603         $self-&gt;{last_name} = $value;
604     }
605
606     return $self-&gt;{last_name};
607 }</code></pre>
608             </td>
609         </tr>
610     </table>
611 </div>
612
613 <div class="slide">
614     <h1>Side by side</h1>
615
616     <table class="side-by-side">
617         <tr>
618             <td>
619                 <pre><code>package Person;
620 use Moose;
621
622 has last_name =&gt; (
623     <span class="match-moose">is  =&gt; 'rw',</span>
624     isa =&gt; 'Str',
625 );</code></pre>
626             </td>
627             <td>
628                 <pre class="small"><code>package Person;
629 use strict;
630 use warnings;
631 use Carp 'confess';
632
633 sub new {
634     my $class = shift;
635     my %args  = @_;
636     my $self  = {};
637
638     if (exists $args{last_name}) {
639         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
640                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
641             if ref($args{last_name});
642         $self-&gt;{last_nane} = $args{last_name};
643     }
644
645     return bless $self, $class;
646 }
647
648 <span class="match-unsweet">sub last_name {
649     my $self = shift;
650
651     if (@_) {
652         my $value = shift;</span>
653         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
654                 . &quot;Validation failed for 'Str' with value $value&quot;
655             if ref($value);
656         <span class="match-unsweet">$self-&gt;{last_name} = $value;
657     }
658
659     return $self-&gt;{last_name};
660 }</span></code></pre>
661             </td>
662         </tr>
663     </table>
664 </div>
665
666 <div class="slide">
667     <h1>Side by side</h1>
668
669     <table class="side-by-side">
670         <tr>
671             <td>
672                 <pre><code>package Person;
673 use Moose;
674
675 has last_name =&gt; (
676     is  =&gt; 'rw',
677     <span class="match-moose">isa =&gt; 'Str',</span>
678 );</code></pre>
679             </td>
680             <td>
681                 <pre class="small"><code>package Person;
682 use strict;
683 use warnings;
684 use Carp 'confess';
685
686 sub new {
687     my $class = shift;
688     my %args  = @_;
689     my $self  = {};
690
691     if (exists $args{last_name}) {
692         <span class="match-unsweet">confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
693                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
694             if ref($args{last_name});</span>
695         $self-&gt;{last_nane} = $args{last_name};
696     }
697
698     return bless $self, $class;
699 }
700
701 sub last_name {
702     my $self = shift;
703
704     if (@_) {
705         my $value = shift;
706         <span class="match-unsweet">confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
707                 . &quot;Validation failed for 'Str' with value $value&quot;
708             if ref($value);</span>
709         $self-&gt;{last_name} = $value;
710     }
711
712     return $self-&gt;{last_name};
713 }</code></pre>
714             </td>
715         </tr>
716     </table>
717 </div>
718
719 <div class="slide">
720     <h1>Side by side</h1>
721
722     <table class="side-by-side">
723         <tr class="incremental">
724             <td>5 lines</td>
725             <td>21 lines</td>
726         </tr>
727         <tr class="incremental">
728             <td>92 characters</td>
729             <td>741 characters</td>
730         </tr>
731         <tr>
732             <td>
733                 <pre><code>package Person;
734 use Moose;
735
736 has last_name =&gt; (
737     is  =&gt; 'rw',
738     isa =&gt; 'Str',
739 );</code></pre>
740             </td>
741             <td>
742                 <pre class="small"><code>package Person;
743 use strict;
744 use warnings;
745 use Carp 'confess';
746
747 sub new {
748     my $class = shift;
749     my %args  = @_;
750     my $self  = {};
751
752     if (exists $args{last_name}) {
753         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
754                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
755             if ref($args{last_name});
756         $self-&gt;{last_nane} = $args{last_name};
757     }
758
759     return bless $self, $class;
760 }
761
762 sub last_name {
763     my $self = shift;
764
765     if (@_) {
766         my $value = shift;
767         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
768                 . &quot;Validation failed for 'Str' with value $value&quot;
769             if ref($value);
770         $self-&gt;{last_name} = $value;
771     }
772
773     return $self-&gt;{last_name};
774 }</code></pre>
775             </td>
776         </tr>
777     </table>
778 </div>
779
780 <div class="slide">
781     <h1>Typo?</h1>
782
783     <pre class="small"><code>sub new {
784     my $class = shift;
785     my %args  = @_;
786     my $self  = {};
787
788     if (exists $args{last_name}) {
789         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
790                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
791             if ref($args{last_name});
792         $self-&gt;{last_nane} = $args{last_name};
793     }
794
795     return bless $self, $class;
796 }</code></pre>
797 </div>
798
799 <div class="slide">
800     <h1>Typo?</h1>
801
802     <pre class="small"><code>if (exists $args{last_name}) {
803     confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
804             . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
805         if ref($args{last_name});
806     $self-&gt;{last_nane} = $args{last_name};
807 }</code></pre>
808 </div>
809
810 <div class="slide">
811     <h1>Typo?</h1>
812
813     <code>$self-&gt;{last_nane} = $args{last_name};</code>
814 </div>
815
816 <div class="slide">
817     <h1>Typo?</h1>
818     <code>$self-&gt;{last_na<span class="highlight">n</span>e}</code>
819 </div>
820
821 <div class="slide">
822     <h1>Why Moose?</h1>
823
824     <pre><code>package Person;
825 use Moose;
826
827 has last_name =&gt; (
828     is  =&gt; 'rw',
829     isa =&gt; 'Str',
830 );</code></pre>
831 </div>
832
833 <div class="slide fake-slide0">
834   <h1>Part 1: Moose Classes</h1>
835 </div>
836
837 <div class="slide">
838   <h1>Moose Classes</h1>
839
840   <ul>
841     <li>Moose classes are Perl packages which <code>use Moose</code></li>
842   </ul>
843 </div>
844
845 <div class="slide">
846   <h1>Moose.pm and Your Class</h1>
847
848   <pre><code>package Person;
849 use Moose;</code></pre>
850
851   <ul>
852     <li><code>Moose.pm</code> provides declarative sugar</li>
853     <li>Turns on <code>strict</code> and <code>warnings</code></li>
854     <li>Creates metaclasses for your class: <code>Person-&gt;meta</code></li>
855     <li>Moose classes automatically inherit from <code>Moose::Object</code></li>
856   </ul>
857 </div>
858
859 <div class="slide">
860   <h1>What <code>Moose::Object</code> Provides</h1>
861
862   <ul>
863     <li>Constructor - <code>new()</code></li>
864     <li>Calls your <code>BUILDARGS()</code> and/or <code>BUILD()</code></li>
865     <li>Calls your <code>DEMOLISH</code> during object destruction</li>
866   </ul>
867 </div>
868
869 <div class="slide">
870   <h1>extends</h1>
871
872   <ul>
873     <li><code>extends</code> is sugar for declaring parent classes</li>
874   </ul>
875
876   <pre><code>package Employee;
877 use Moose;
878 <span class="highlight">extends 'Person';</span></code></pre>
879 </div>
880
881 <div class="slide">
882   <h1>extends</h1>
883
884   <ul>
885     <li>Each call to <code>extends</code> <strong>resets</strong> your parents</li>
886   </ul>
887
888   <h2 class="wrong">WRONG</h2>
889
890   <pre><code>package EvilEmployee;
891 use Moose;
892 extends 'Person';
893 extends 'Thief';</code></pre>
894
895   <h2 class="right">RIGHT</h2>
896
897   <pre><code>package EvilEmployee;
898 use Moose;
899 extends 'Person', 'Thief';</code></pre>
900 </div>
901
902 <div class="slide">
903   <h1>Extending un-Moose-y Parents</h1>
904
905   <pre><code>package My::LWP;
906 use Moose;
907 extends 'LWP';</code></pre>
908
909   <ul>
910     <li>No <code>Moose::Object</code>, so ...
911       <ul>
912         <li>No attribute-handling <code>new()</code></li>
913         <li>No <code>BUILDARGS()</code> or <code>BUILD()</code></li>
914         <li>No <code>DEMOLISH()</code></li>
915       </ul>
916     </li>
917     <li>But see <code>MooseX::NonMoose</code> for a workaround</li>
918   </ul>
919 </div>  
920
921 <div class="slide">
922   <h1><code>overrides</code> and <code>super</code></h1>
923
924   <ul>
925     <li><code>overrides</code> is another method modifier</li>
926     <li>An alternative to Perl's <code>SUPER::</code></li>
927   </ul>
928 </div>
929
930 <div class="slide">
931   <h1><code>overrides</code> and <code>super</code></h1>
932
933   <pre><code>package Employee;
934 use Moose;
935
936 <span class="current">extends 'Person';</span>
937
938 <span class="incremental">overrides</span> work =&gt; sub {
939     my $self = shift;
940
941     die "Pay me first" unless $self-&gt;got_paid;
942     <span class="incremental">super();</span>
943 }<span class="incremental">;</span></code></pre>
944 </div>
945
946 <div class="slide">
947   <h1>Caveat <code>super</code></h1>
948
949   <ul>
950     <li>Mostly like <code>$self-&gt;SUPER::work(@_)</code></li>
951     <li><strong>But</strong> cannot change <code>@_</code>!</li>
952     <li>Binds the parent's method at compile time</li>
953   </ul>
954 </div>
955
956 <div class="slide">
957   <h1>Attributes (Part 1)</h1>
958
959   <ul>
960     <li><code>has 'foo'</code></li>
961     <li>Use <code>is =&gt; 'ro'</code> or <code>is =&gt; 'rw'</code></li>
962     <li>Attributes without "is" have no accessors</li>
963   </ul>
964 </div>
965
966 <div class="slide">
967   <h1>Read-write attributes</h1>
968
969   <pre><code>package Person;
970 use Moose;
971
972 has first_name =&gt; ( <span class="highlight">is =&gt; 'rw'</span> );
973
974 my $person =
975     Person-&gt;new( first_name =&gt; 'Dave' );
976
977 $person-&gt;first_name('Stevan');
978 print $person-&gt;first_name; # Stevan</code></pre>
979
980 </div>
981
982 <div class="slide">
983   <h1>Read-only attributes</h1>
984
985   <pre><code>package Person;
986 use Moose;
987
988 has first_name =&gt; ( <span class="highlight">is =&gt; 'ro'</span> );
989
990 my $person =
991     Person-&gt;new( first_name =&gt; 'Dave' );
992
993 $person-&gt;first_name('Stevan');
994 print $person-&gt;first_name; # Dave</code></pre>
995
996 </div>
997
998 <div class="slide">
999   <h1>There is More to Come</h1>
1000
1001   <ul>
1002     <li>Attributes have a <em>lot</em> of features</li>
1003   </ul>
1004 </div>
1005
1006 <div class="slide">
1007   <h1>Cleaning Up Moose Droppings</h1>
1008
1009   <pre><code>package Person;
1010 use Moose;
1011
1012 # true
1013 Person->can('extends');</code></pre>
1014
1015   <ul>
1016     <li>Not very hygienic</li>
1017   </ul>
1018 </div>
1019
1020 <div class="slide">
1021   <h1>Cleaning Up Moose Droppings</h1>
1022
1023   <pre><code>package Person;
1024 use Moose;
1025
1026 ...
1027
1028 no Moose;
1029
1030 # false
1031 Person->can('extends');</code></pre>
1032 </div>
1033
1034 <div class="slide">
1035   <h1>No Moose</h1>
1036
1037   <ul>
1038     <li><code>no Moose</code> at the end of a package is a best practice</li>
1039     <li>Just do it</li>
1040   </ul>
1041 </div>
1042
1043 <div class="slide">
1044   <h1>Immutability</h1>
1045
1046   <ul>
1047     <li><span style="font-family: URW Chancery L; font-size: 140%">Stevan's Incantation of Fleet-Footedness</span></li>
1048   </ul>
1049
1050   <pre><code>package Person;
1051 use Moose;
1052
1053 <span class="highlight">__PACKAGE__->meta->make_immutable;</span></code></pre>
1054 </div>
1055
1056 <div class="slide">
1057   <h1>What <code>make_immutable</code> does</h1>
1058
1059   <ul>
1060     <li>Magic</li>
1061     <li>Uses <code>eval</code> to "inline" a constructor</li>
1062     <li>Memoizes a lot of meta-information</li>
1063     <li>Makes loading your class slower</li>
1064     <li>Makes object creation <em>much</em> faster</li>
1065   </ul>
1066 </div>
1067
1068 <div class="slide">
1069   <h1>When to Immutabilize?</h1>
1070
1071   <ul>
1072     <li><em>Almost</em> always</li>
1073     <li>Startup time vs execution time</li>
1074   </ul>
1075 </div>
1076
1077 <div class="slide">
1078   <h1>Classes Summary</h1>
1079
1080   <ul>
1081     <li><code>use Moose</code></li>
1082     <li><code>Class-&gt;meta</code></li>
1083     <li><code>Moose::Object</code> base class</li>
1084     <li><code>extends</code>, <code>overrides</code>, and <code>super</code></li>
1085     <li>Simple attributes: <code>has</code>, <code>is&nbsp;=&gt;&nbsp;'ro'</code>, &amp; <code>is&nbsp;=&gt;&nbsp;'rw'</code></li>
1086     <li><code>no Moose</code></li>
1087     <li><code>__PACKAGE__-&gt;meta-&gt;make_immutable</code></li>
1088   </ul>
1089 </div>
1090
1091 <div class="slide">
1092   <h1>Exercises</h1>
1093
1094   <pre>$ cd exercises
1095 $ perl bin/prove -lv t/00-prereq.t
1096
1097 Missing anything? Install it. (see tarballs/)
1098
1099 # perl bin/prove -lv t/01-classes.t
1100
1101 Iterate til this passes all its tests</pre>
1102 </div>
1103
1104 <div class="slide fake-slide0">
1105   <h1>Part 2: Roles</h1>
1106 </div>
1107
1108 <div class="slide">
1109   <h1>Just What Is a Role?</h1>
1110
1111   <ul>
1112     <li>Mixin? Interface? Trait?</li>
1113     <li>Yes ... and more!</li>
1114   </ul>
1115 </div>
1116
1117 <div class="slide">
1118   <h1>Roles Can Have State <strong>and</strong> Behavior</h1>
1119
1120   <pre><code>package HasPermissions;
1121 use Moose::Role;
1122
1123 <span class="current"># state
1124 has access_level =&gt; ( is =&gt; 'rw' );</span>
1125
1126 <span class="incremental"># behavior
1127 sub can_access {
1128     my $self     = shift;
1129     my $required = shift;
1130
1131     return $self-&gt;access_level &gt;= $required;
1132 }</span></code></pre>
1133
1134 </div>
1135
1136 <div class="slide">
1137   <h1>Roles Can Define Interfaces</h1>
1138
1139   <pre><code>package Printable;
1140 use Moose::Role;
1141
1142 requires 'as_string';</code></pre>
1143 </div>
1144
1145 <div class="slide">
1146   <h1>Roles Can Do All Three</h1>
1147
1148   <pre><code>package Printable;
1149 use Moose::Role;
1150
1151 requires 'as_string';
1152
1153 has has_been_printed =&gt; ( is =&gt; 'rw'  );
1154
1155 sub print {
1156     my $self = shift;
1157     print $self-&gt;as_string;
1158     $self-&gt;has_been_printed(1);
1159 }</code></pre>
1160 </div>
1161
1162 <div class="slide">
1163   <h1>Classes Consume Roles</h1>
1164
1165   <pre><code>package Person;
1166 use Moose;
1167
1168 with 'HasPermissions';</code></pre>
1169 </div>
1170
1171 <div class="slide">
1172   <h1>Classes Consume Roles</h1>
1173
1174 <pre><code>my $person = Person-&gt;new(
1175     first_name => 'Kenichi',
1176     last_name => 'Asai',
1177     access_level =&gt; 42,
1178 );
1179
1180 print $person-&gt;full_name
1181     . ' has '
1182     . $person-&gt;can_access(42)
1183         ? 'great power'
1184         : 'little power';</code></pre>
1185 </div>
1186
1187 <div class="slide">
1188   <h1>Roles in Practice</h1>
1189
1190   <ul>
1191     <li>Consuming a role =~ inlining the role</li>
1192   </ul>
1193 </div>
1194
1195 <div class="slide">
1196   <h1>In Other Words ...</h1>
1197
1198 <pre><code>package Person;
1199 use Moose;
1200
1201 <span class="highlight">with 'Printable';</span></code></pre>
1202 </div>
1203
1204 <div class="slide">
1205   <h1>In Other Words ...</h1>
1206
1207 <pre><code>package Person;
1208 use Moose;
1209
1210 <span class="delete">with 'Printable';</span>
1211
1212 <span class="highlight">has has_been_printed =&gt; ( is =&gt; 'rw'  );
1213
1214 sub print {
1215     my $self = shift;
1216     print $self-&gt;as_string;
1217     $self-&gt;has_been_printed(1);
1218 }</span></code></pre>
1219 </div>
1220
1221 <div class="slide">
1222   <h1>Except</h1>
1223
1224   <ul>
1225     <li>Role consumption is introspectable</li>
1226   </ul>
1227
1228   <pre><code>if ( Person-&gt;does('Printable') ) { ... }
1229
1230 # or ...
1231
1232 if ( Person-&gt;meta-&gt;does('Printable') ) { ... }</code></pre>
1233
1234 </div>
1235
1236 <div class="slide">
1237   <h1>These Names Are the Same</h1>
1238
1239   <ul>
1240     <li>What if a role and class define the same method?</li>
1241     <li>A class's <em>local</em> methods win over the role's</li>
1242     <li>The role's methods win over the class's <em>inherited</em> methods</li>
1243   </ul>
1244 </div>
1245
1246 <div class="slide">
1247   <h1>Conflicts Between Roles</h1>
1248
1249   <ul>
1250     <li>Two roles with a method of the same name</li>
1251     <li>Generates a compile-time error when consumed by a class</li>
1252   </ul>
1253 </div>
1254
1255 <div class="slide">
1256   <h1>Conflict Example</h1>
1257
1258   <pre><code>package IsFragile;
1259 use Moose::Role;
1260
1261 sub break { ... }
1262
1263 package CanBreakdance;
1264 use Moose::Role;
1265
1266 sub break { ... }</code></pre>
1267 </div>
1268
1269 <div class="slide">
1270   <h1>Conflict Example</h1>
1271
1272   <pre><code>package FragileDancer;
1273 use Moose;
1274
1275 <span class="highlight">with 'IsFragile', 'CanBreakdance';</span></code></pre>
1276
1277   <ul>
1278     <li>Only one <code>with</code>!</li>
1279   </ul>
1280 </div>
1281
1282 <div class="slide">
1283   <h1>Conflict Resolution</h1>
1284
1285   <ul>
1286     <li>The consuming class must resolve the conflict by implementing th emethod</li>
1287     <li>Can use some combination of method exclusion and aliasing</li>
1288   </ul>
1289 </div>
1290
1291 <div class="slide">
1292   <h1>Method Aliasing</h1>
1293
1294   <pre><code>package FragileDancer;
1295 use Moose;
1296
1297 <span class="highlight">with 'IsFragile' =>
1298          { alias =>
1299                { break => 'break_bone' } },
1300      'CanBreakdance' =>
1301          { alias =>
1302                { break => 'break_it_down' } };</span></code></pre>
1303
1304   <ul>
1305     <li>Renames the roles' methods</li>
1306     <li>Still conflicts, need to <code>exclude</code> as well</li>
1307   </ul>
1308 </div>
1309
1310 <div class="slide">
1311   <h1>Method Exclusion</h1>
1312
1313   <pre><code>package FragileDancer;
1314 use Moose;
1315
1316 <span class="highlight">with 'IsFragile' =>
1317          { alias =>
1318                { break => 'break_bone' },
1319            exclude => 'break' },
1320      'CanBreakdance' =>
1321          { alias =>
1322                { break => 'break_dance' },
1323            exclude => 'break' };</span></code></pre>
1324 </div>
1325
1326 <div class="slide">
1327   <h1>And then ...</h1>
1328
1329   <pre><code>package FragileDancer;
1330 use Moose;
1331
1332 sub break {
1333     my $self = shift;
1334
1335     $self->break_dance;
1336     if ( rand(1) < 0.5 ) {
1337         $self->break_bone;
1338     }
1339 }</code></pre>
1340 </div>
1341
1342 <div class="slide">
1343   <h1>Still Full of Fail</h1>
1344
1345   <ul>
1346     <li>Roles are also about semantics!</li>
1347     <li>We've fulfilled the letter and lost the spirit</li>
1348     <li>Roles have a <em>meaning</em></li>
1349     <li>Think twice before blindly aliasing and excluding methods!</li>
1350   </ul>
1351 </div>
1352
1353 <div class="slide">
1354   <h1>Hot Role-on-Role Action</h1>
1355
1356   <pre><code>package Comparable;
1357 use Moose::Role;
1358
1359 requires 'compare';</code></pre>
1360 </div>
1361
1362 <div class="slide">
1363   <h1>Hot Role-on-Role Action</h1>
1364
1365   <pre><code>package TestsEquality;
1366 use Moose::Role;
1367
1368 with 'Comparable';
1369
1370 sub is_equal {
1371     my $self = shift;
1372     return $self->compare(@_) == 0;
1373 }</code></pre>
1374 </div>
1375
1376 <div class="slide">
1377   <h1>And then ...</h1>
1378
1379   <pre><code>package Integer;
1380 use Moose;
1381
1382 with 'TestsEquality';
1383
1384 # Satisfies the Comparable role
1385 sub compare { ... }
1386
1387 Integer->does('TestsEquality'); # true
1388 Integer->does('Comparable'); # also true!</code></pre>
1389 </div>
1390
1391 <div class="slide">
1392   <h1>Name Conflicts Between Roles</h1>
1393
1394   <pre><code>package HasSubProcess;
1395 use Moose::Role;
1396
1397 <span class="highlight">sub execute { ... }</span>
1398
1399 package Killer;
1400 use Moose::Role;
1401
1402 with 'HasSubProcess';
1403
1404 <span class="highlight">sub execute { ... }</span></code></pre>
1405 </div>
1406
1407 <div class="slide">
1408   <h1>Delayed Conflict</h1>
1409
1410   <pre><code>package StateOfTexas;
1411 with 'Killer';</code></pre>
1412
1413   <ul>
1414     <li><code>StateOfTexas</code> must implement its own <code>execute</code></li>
1415     <li>But loading the <code>Killer</code> role by itself does not cause an error</li>
1416   </ul>
1417 </div>
1418
1419 <div class="slide">
1420   <h1>Roles as Interfaces</h1>
1421
1422   <ul>
1423     <li>Roles can <code>require</code> methods of their consumers</li>
1424     <li>Compile-time checks</li>
1425     <li>Method must exist when the role is consumed</li>
1426   </ul>
1427 </div>
1428
1429 <div class="slide">
1430   <h1>The Attribute Gotcha</h1>
1431
1432 <pre><code>package HasSize;
1433 use Moose::Role;
1434
1435 <span class="current">requires 'size';</span>
1436
1437 package Shirt;
1438 use Moose;
1439
1440 <span class="incremental">with 'HasSize';
1441
1442 has size => ( is => 'ro' );</span></code></pre>
1443 </div>
1444
1445 <div class="slide">
1446   <h1>The Attribute Gotcha Workaround</h1>
1447
1448   <pre><code>package HasSize;
1449 use Moose::Role;
1450
1451 requires 'size';
1452
1453 package Shirt;
1454 use Moose;
1455
1456 has size => ( is => 'ro' );
1457
1458 with 'HasSize';</code></pre>
1459 </div>
1460
1461 <div class="slide">
1462   <h1>Compile-time Is a Lie</h1>
1463
1464   <ul>
1465     <li>Really, it's <em>package load</em> time</li>
1466     <li>That's run-time, but before the "real" run-time</li>
1467     <li>Moose does not rewire Perl, it's just sugar!</li>
1468     <li>(but <code>MooseX::Declare</code> <em>does</em> rewire Perl)</li>
1469   </ul>
1470 </div>
1471
1472 <div class="slide">
1473   <h1>Enforcing Roles</h1>
1474
1475   <pre><code>package Comparison;
1476 use Moose;
1477
1478 has [ 'left', 'right' ] => (
1479     is   => 'ro',
1480     <span class="highlight">does => 'Comparable',</span>
1481 );
1482 </code></pre>
1483
1484   <ul>
1485     <li>A sneak peek at type constraints</li>
1486   </ul>
1487 </div>
1488
1489
1490 <div class="slide">
1491   <h1>Roles Can Be Applied to Objects</h1>
1492
1493   <pre><code>use Moose::Util qw( apply_all_roles );
1494
1495 my $fragile_person = Person->new( ... );
1496 apply_all_roles( $fragile_person, 'IsFragile' );</code></pre>
1497
1498   <ul>
1499     <li>Does not change the <code>Person</code> class</li>
1500     <li>Works with non-Moose classes, great for monkey-patching!</li>
1501   </ul>
1502 </div>
1503
1504 <div class="slide">
1505   <h1>Roles Are Dirty Too</h1>
1506
1507   <ul>
1508     <li>Once again, clean up those Moose droppings</li>
1509   </ul>
1510
1511   <pre><code>package Comparable;
1512 use Moose::Role;
1513
1514 requires 'compare';
1515
1516 <span class="highlight">no Moose::Role;</span></code></pre>
1517
1518   <ul>
1519     <li>But roles cannot be made immutable</li>
1520   </ul>
1521 </div>
1522
1523 <div class="slide">
1524   <h1>The Zen of Roles</h1>
1525
1526   <ul>
1527     <li>Roles represent discrete units of ...
1528       <ul>
1529         <li>state</li>
1530         <li>behavior</li>
1531         <li>interface</li>
1532       </ul>
1533     </li>
1534     <li>Roles are shareable between unrelated classes</li>
1535     <li>Roles are what a class <em>does</em>, not what it <em>is</em></li>
1536     <li>Roles <em>add</em> functionality, inheritance <em>specializes</em></li>
1537   </ul>
1538 </div>
1539
1540 <div class="slide">
1541   <h1>Abstract Examples</h1>
1542
1543   <ul>
1544     <li>Human <em>@ISA</em> Animal</li>
1545     <li>Human <em>does</em> Toolmaker (as <em>does</em> Chimpanzee)</li>
1546     <li>Car <em>@ISA</em> Vehicle</li>
1547     <li>Car <em>does</em> HasEngine</li>
1548   </ul>
1549 </div>
1550
1551 <div class="slide">
1552   <h1>Real Examples</h1>
1553
1554   <ul>
1555     <li>Objects representing SQL database components and queries
1556       <ul>
1557         <li>Schema, Table, Column, ColumnAlias</li>
1558         <li>Select, Insert, Update, Delete</li>
1559       </ul>
1560     </li>
1561   </ul>
1562 </div>
1563
1564 <div class="slide">
1565   <h1>Real Examples</h1>
1566
1567   <ul>
1568     <li>Column and ColumnAlias both <em>do</em> ColumnLike</li>
1569     <li>ColumnLike things can be used in certain parts of queries</li>
1570     <li>All queries <em>do</em> HasWhereClause</li>
1571     <li>Select <em>does</em> Comparable and Selectable (for subselects)</li>
1572     <li>A where clause requires its components to <em>do</em> Comparable</li>
1573   </ul>
1574 </div>
1575
1576 <div class="slide">
1577   <h1>Exercises</h1>
1578
1579   <pre>$ cd exercises
1580 # perl bin/prove -lv t/02-roles.t
1581
1582 Iterate til this passes all its tests</pre>
1583 </div>
1584
1585 </div> 
1586 </body>
1587 </html>
1588
1589 <!--
1590
1591 Copyright 2009 David Rolsky. All Rights Reserved.
1592
1593 This work is licensed under a Creative Commons Attribution-Share Alike
1594 3.0 United States License See
1595 http://creativecommons.org/licenses/by-sa/3.0/us/ for details.
1596
1597 -->