dcae330f69c7c2a392796c93a536c3d73579b257
[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 <!-- metadata -->
9 <meta name="generator" content="S5" />
10 <meta name="version" content="S5 1.2a2" />
11 <meta name="author" content="Eric A. Meyer" />
12 <meta name="company" content="Complex Spiral Consulting" />
13 <!-- configuration parameters -->
14 <meta name="defaultView" content="slideshow" />
15 <meta name="controlVis" content="hidden" />
16 <!-- style sheet links -->
17 <link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
18 <link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
19 <link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
20 <link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
21 <!-- embedded styles -->
22 <style type="text/css" media="all">
23 .imgcon {width: 525px; margin: 0 auto; padding: 0; text-align: center;}
24 #anim {width: 270px; height: 320px; position: relative; margin-top: 0.5em;}
25 #anim img {position: absolute; top: 42px; left: 24px;}
26 img#me01 {top: 0; left: 0;}
27 img#me02 {left: 23px;}
28 img#me04 {top: 44px;}
29 img#me05 {top: 43px;left: 36px;}
30 </style>
31 <!-- S5 JS -->
32 <script src="ui/default/slides.js" type="text/javascript"></script>
33 <link rel="stylesheet" href="ui/custom.css" type="text/css" />
34 </head>
35 <body>
36
37 <div class="layout">
38 <div id="controls"><!-- DO NOT EDIT --></div>
39 <div id="currentSlide"><!-- DO NOT EDIT --></div>
40 <div id="header"></div>
41 <div id="footer">
42   <h2>Introduction to Moose</h2>
43 </div>
44 </div>
45
46 <div class="presentation">
47
48 <div class="slide">
49   <h1>Introduction to Moose</h1>
50   <h2>YAPC 2009</h2>
51 </div>
52
53 <div class="slide">
54   <h1>Moose Summed Up</h1>
55
56   <ul>
57     <li><strong>Declarative</strong> OO sugar</li>
58     <li>Introspectable</li>
59     <li>Extensible</li>
60   </ul>
61 </div>
62
63 <div class="slide">
64   <h1>Concepts</h1>
65
66   <ul>
67     <li>Moose builds on Perl 5's native OO</li>
68     <li>Borrows ideas from other languages, notably Perl 6</li>
69     <li>Provides semantics for common operations</li>
70   </ul>
71 </div>
72
73 <div class="slide">
74   <h1>Classes</h1>
75
76   <ul>
77     <li>
78       Classes have ...
79       <ul>
80         <li>Attributes</li>
81         <li>Methods</li>
82         <li>Superclasses</li>
83         <li>Method modifiers</li>
84         <li>Constructor and destructor</li>
85         <li>One metaclass object</li>
86       </ul>
87     </li>
88     <li>Classes do roles</li>
89   </ul>
90 </div>
91
92 <div class="slide">
93   <h1>Class Example</h1>
94
95   <pre><code>package Person;
96 <span class="highlight">use Moose;</span></code></pre>
97
98   <ul>
99     <li>Poof, a Moose-based class!</li>
100   </ul>
101 </div>
102
103 <div class="slide">
104   <h1>Attributes</h1>
105
106   <ul>
107     <li>Aka property, slot, field, member variable</li>
108     <li>A piece of data owned by an object</li>
109   </ul>
110 </div>
111
112 <div class="slide">
113   <h1>Attributes</h1>
114
115   <ul>
116     <li>
117       Attributes have ...
118       <ul>
119         <li>Access-control (read-only vs read-write)</li>
120         <li>An optional type</li>
121         <li>Accessor methods</li>
122         <li>Delegation methods</li>
123         <li>Optional default value</li>
124         <li>Many more features</li>
125       </ul>
126     </li>
127     <li>Stored in the object, but don't worry about that</li>
128   </ul>
129 </div>
130
131 <div class="slide">
132   <h1>Attribute Example</h1>
133
134   <pre><code>package Person;
135 use Moose;
136
137 <span class="highlight">has 'first_name' =&gt; ( is =&gt; 'rw' );</span></code></pre>
138
139 </div>
140
141 <div class="slide">
142   <h1>Methods</h1>
143
144   <ul>
145     <li>Nothing fancy here, just Perl subroutines</li>
146   </ul>
147
148   <pre><code>package Person;
149 use Moose;
150
151 <span class="highlight">sub greet { ... }</span></code></pre>
152 </div>
153
154 <div class="slide">
155   <h1>Roles</h1>
156
157   <ul>
158     <li>Classes <strong>do</strong> (or consume) roles</li>
159     <li>Similar to mixins and Java interfaces</li>
160   </ul>
161 </div>
162
163 <div class="slide">
164   <h1>Roles</h1>
165
166   <ul>
167     <li>Like classes, can have attributes, methods, do roles</li>
168     <li>Roles can require methods</li>
169     <li>Roles are composed (flattened) into classes</li>
170   </ul>
171 </div>
172
173 <div class="slide">
174   <h1>Role Example</h1>
175
176 <pre><code>package HasPermissions;
177 <span class="highlight">use Moose::Role;</span>
178
179 has is_admin =&gt; ( is =&gt; 'rw' );</code></pre>
180 </div>
181
182 <div class="slide">
183   <h1>Role Example</h1>
184
185   <p>
186     And then ...
187   </p>
188   
189 <pre><code>package Person;
190 use Moose;
191
192 <span class="highlight">with 'HasPermissions';</span></code></pre>
193 </div>
194
195 <div class="slide">
196   <h1>Method Modifiers</h1>
197
198   <ul>
199     <li>AKA advice</li>
200     <li>&quot;<strong>Before</strong> foo(), do this first&quot;</li>
201     <li>&quot;Do this <strong>after</strong> foo()</li>
202     <li>&quot;Put this code <strong>around</strong> foo()&quot;</li>
203   </ul>
204 </div>
205
206 <div class="slide">
207   <h1>Before &amp; After</h1>
208
209 <pre><code>before 'foo'
210     =&gt; sub { warn 'About to call foo()' };
211
212 after  'foo'
213     =&gt; sub { warn 'Leaving foo()' };</code></pre>
214
215 </div>
216
217 <div class="slide">
218   <h1>Around</h1>
219
220 <pre><code>around 'foo' =&gt; sub {
221     my $real_foo = shift;
222     my $self     = shift;
223
224     warn 'Just before foo()';
225     my @return =
226         $self-&gt;$real_foo( @_, bar =&gt; 42 );
227
228     return ( @return, 'modify return values' );
229 };</code></pre>
230 </div>
231
232 <div class="slide">
233   <h1>Type Constraints</h1>
234
235   <ul>
236     <li>NOT A FULL-BLOWN TYPE SYSTEM!</li>
237     <li>But still darn useful</li>
238     <li>Constrain attribute values</li>
239     <li>Coerce from other types</li>
240   </ul>
241 </div>
242
243 <div class="slide">
244   <h1>Type Constraint Example</h1>
245
246 <pre><code>package Person;
247 use Moose;
248
249 has 'weight' =&gt; ( is =&gt; 'ro', <span class="highlight">isa =&gt; 'Int'</span> );
250
251 # kaboom
252 Person-&gt;new( weight =&gt; 'fat' );</code></pre>
253 </div>
254
255 <div class="slide">
256   <h1>Delegation</h1>
257
258   <ul>
259     <li>Attributes can define delegations</li>
260     <li>Lets you hide some implementation details</li>
261     <li>Fewer objects to chase around</li>
262   </ul>
263 </div>
264
265 <div class="slide">
266   <h1>Delegation</h1>
267
268 <pre><code>package Person;
269 use Moose;
270
271 has 'blog_uri' =&gt; (
272     is      =&gt; 'rw',
273     isa     =&gt; 'URI',
274     <span class="highlight">handles =&gt; { 'blog_hostname' =&gt; 'host' },</span>
275 );
276
277 <span class="highlight">$person->blog_hostname;</span>
278 # really calls $person->blog_uri->host
279 </div>
280
281 <div class="slide">
282   <h1>Constructors</h1>
283
284   <ul>
285     <li>Moose creates <code>new()</code> for you</li>
286     <li>Provide an optional <code>BUILDARGS()</code> and <code>BUILD()</code></li>
287   </ul>
288 </div>
289
290 <div class="slide">
291   <h1>Destructors</h1>
292
293   <ul>
294     <li>Provide an optional <code>DEMOLISH()</code></li>
295   </ul>
296 </div>
297
298 <div class="slide">
299   <h1>Moose Meta-API</h1>
300
301   <ul>
302     <li>Answers questions like ...
303       <ul>
304         <li>What methods does this class have?</li>
305         <li>What are its parents?</li>
306         <li>What attributes does it have (including inherited attributes)?</li>
307         <li>What roles does it do?</li>
308         <li>Much, much, more</li>
309       </ul>
310     </li>
311   </ul>
312 </div>
313
314 <div class="slide">
315   <h1>Moose Meta-API</h1>
316
317   <ul>
318     <li>Not just for introspection ...
319       <ul>
320         <li>Add methods, attributes, roles, etc</li>
321         <li>Extend and alter core features</li>
322       </ul>
323     </li>
324   </ul>
325 </div>
326
327 <div class="slide">
328   <h1>Why Moose?</h1>
329
330   <ul>
331     <li>A quick bit of propoganda ...</li>
332   </ul>
333 </div>
334
335 <div class="slide">
336   <h1>With Moose</h1>
337
338   <pre><code>package Person;
339 use Moose;
340
341 has last_name =&gt; (
342     is  =&gt; 'rw',
343     isa =&gt; 'Str',
344 );</code></pre>
345 </div>
346
347 <div class="slide">
348     <h1>Without Moose</h1>
349
350     <pre class="small"><code>package Person;
351 use strict;
352 use warnings;
353 use Carp 'confess';
354
355 sub new {
356     my $class = shift;
357     my %args  = @_;
358     my $self  = {};
359
360     if (exists $args{last_name}) {
361         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
362                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
363             if ref($args{last_name});
364         $self-&gt;{last_nane} = $args{last_name};
365     }
366
367     return bless $self, $class;
368 }
369
370 sub last_name {
371     my $self = shift;
372
373     if (@_) {
374         my $value = shift;
375         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
376                 . &quot;Validation failed for 'Str' with value $value&quot;
377             if ref($value);
378         $self-&gt;{last_name} = $value;
379     }
380
381     return $self-&gt;{last_name};
382 }</code></pre>
383
384 </div>
385
386 <div class="slide">
387     <h1>Side by side</h1>
388
389     <table class="side-by-side">
390         <tr>
391           <td>
392             <pre><code>package Person;
393 use Moose;
394
395 has last_name =&gt; (
396     is  =&gt; 'rw',
397     isa =&gt; 'Str',
398 );</code></pre>
399             </td>
400             <td>
401                 <pre class="small"><code>package Person;
402 use strict;
403 use warnings;
404 use Carp 'confess';
405
406 sub new {
407     my $class = shift;
408     my %args  = @_;
409     my $self  = {};
410
411     if (exists $args{last_name}) {
412         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
413                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
414             if ref($args{last_name});
415         $self-&gt;{last_nane} = $args{last_name};
416     }
417
418     return bless $self, $class;
419 }
420
421 sub last_name {
422     my $self = shift;
423
424     if (@_) {
425         my $value = shift;
426         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
427                 . &quot;Validation failed for 'Str' with value $value&quot;
428             if ref($value);
429         $self-&gt;{last_name} = $value;
430     }
431
432     return $self-&gt;{last_name};
433 }</code></pre>
434             </td>
435         </tr>
436     </table>
437
438 </div>
439
440 <div class="slide">
441     <h1>Side by side</h1>
442
443     <table class="side-by-side">
444         <tr>
445             <td>
446                 <pre><code><span class="match-moose">package Person;</span>
447 use Moose;
448
449 has last_name =&gt; (
450     is  =&gt; 'rw',
451     isa =&gt; 'Str',
452 );</code></pre>
453             </td>
454             <td>
455                 <pre class="small"><code><span class="match-unsweet">package Person;</span>
456 use strict;
457 use warnings;
458 use Carp 'confess';
459
460 sub new {
461     my $class = shift;
462     my %args  = @_;
463     my $self  = {};
464
465     if (exists $args{last_name}) {
466         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
467                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
468             if ref($args{last_name});
469         $self-&gt;{last_nane} = $args{last_name};
470     }
471
472     return bless $self, $class;
473 }
474
475 sub last_name {
476     my $self = shift;
477
478     if (@_) {
479         my $value = shift;
480         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
481                 . &quot;Validation failed for 'Str' with value $value&quot;
482             if ref($value);
483         $self-&gt;{last_name} = $value;
484     }
485
486     return $self-&gt;{last_name};
487 }</code></pre>
488             </td>
489         </tr>
490     </table>
491 </div>
492
493 <div class="slide">
494     <h1>Side by side</h1>
495
496     <table class="side-by-side">
497         <tr>
498             <td>
499                 <pre><code>package Person;
500 <span class="match-moose">use Moose;</span>
501
502 has last_name =&gt; (
503     is  =&gt; 'rw',
504     isa =&gt; 'Str',
505 );</code></pre>
506             </td>
507             <td>
508                 <pre class="small"><code>package Person;
509 <span class="match-unsweet">use strict;
510 use warnings;
511 use Carp 'confess';
512
513 sub new {
514     my $class = shift;
515     my %args  = @_;
516     my $self  = {};</span>
517
518     if (exists $args{last_name}) {
519         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
520                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
521             if ref($args{last_name});
522         $self-&gt;{last_nane} = $args{last_name};
523     }
524
525     <span class="match-unsweet">return bless $self, $class;
526 }</span>
527
528 sub last_name {
529     my $self = shift;
530
531     if (@_) {
532         my $value = shift;
533         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
534                 . &quot;Validation failed for 'Str' with value $value&quot;
535             if ref($value);
536         $self-&gt;{last_name} = $value;
537     }
538
539     return $self-&gt;{last_name};
540 }</code></pre>
541             </td>
542         </tr>
543     </table>
544 </div>
545
546 <div class="slide">
547     <h1>Side by side</h1>
548
549     <table class="side-by-side">
550         <tr>
551             <td>
552                 <pre><code>package Person;
553 use Moose;
554
555 <span class="match-moose">has last_name =&gt; (</span>
556     is  =&gt; 'rw',
557     isa =&gt; 'Str',
558 <span class="match-moose">);</span></code></pre>
559             </td>
560             <td>
561                 <pre class="small"><code>package Person;
562 use strict;
563 use warnings;
564 use Carp 'confess';
565
566 sub new {
567     my $class = shift;
568     my %args  = @_;
569     my $self  = {};
570
571     <span class="match-unsweet">if (exists $args{last_name}) {</span>
572         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
573                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
574             if ref($args{last_name});
575         <span class="match-unsweet">$self-&gt;{last_nane} = $args{last_name};
576     }</span>
577
578     return bless $self, $class;
579 }
580
581 sub last_name {
582     my $self = shift;
583
584     if (@_) {
585         my $value = shift;
586         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
587                 . &quot;Validation failed for 'Str' with value $value&quot;
588             if ref($value);
589         $self-&gt;{last_name} = $value;
590     }
591
592     return $self-&gt;{last_name};
593 }</code></pre>
594             </td>
595         </tr>
596     </table>
597 </div>
598
599 <div class="slide">
600     <h1>Side by side</h1>
601
602     <table class="side-by-side">
603         <tr>
604             <td>
605                 <pre><code>package Person;
606 use Moose;
607
608 has last_name =&gt; (
609     <span class="match-moose">is  =&gt; 'rw',</span>
610     isa =&gt; 'Str',
611 );</code></pre>
612             </td>
613             <td>
614                 <pre class="small"><code>package Person;
615 use strict;
616 use warnings;
617 use Carp 'confess';
618
619 sub new {
620     my $class = shift;
621     my %args  = @_;
622     my $self  = {};
623
624     if (exists $args{last_name}) {
625         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
626                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
627             if ref($args{last_name});
628         $self-&gt;{last_nane} = $args{last_name};
629     }
630
631     return bless $self, $class;
632 }
633
634 <span class="match-unsweet">sub last_name {
635     my $self = shift;
636
637     if (@_) {
638         my $value = shift;</span>
639         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
640                 . &quot;Validation failed for 'Str' with value $value&quot;
641             if ref($value);
642         <span class="match-unsweet">$self-&gt;{last_name} = $value;
643     }
644
645     return $self-&gt;{last_name};
646 }</span></code></pre>
647             </td>
648         </tr>
649     </table>
650 </div>
651
652 <div class="slide">
653     <h1>Side by side</h1>
654
655     <table class="side-by-side">
656         <tr>
657             <td>
658                 <pre><code>package Person;
659 use Moose;
660
661 has last_name =&gt; (
662     is  =&gt; 'rw',
663     <span class="match-moose">isa =&gt; 'Str',</span>
664 );</code></pre>
665             </td>
666             <td>
667                 <pre class="small"><code>package Person;
668 use strict;
669 use warnings;
670 use Carp 'confess';
671
672 sub new {
673     my $class = shift;
674     my %args  = @_;
675     my $self  = {};
676
677     if (exists $args{last_name}) {
678         <span class="match-unsweet">confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
679                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
680             if ref($args{last_name});</span>
681         $self-&gt;{last_nane} = $args{last_name};
682     }
683
684     return bless $self, $class;
685 }
686
687 sub last_name {
688     my $self = shift;
689
690     if (@_) {
691         my $value = shift;
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 $value&quot;
694             if ref($value);</span>
695         $self-&gt;{last_name} = $value;
696     }
697
698     return $self-&gt;{last_name};
699 }</code></pre>
700             </td>
701         </tr>
702     </table>
703 </div>
704
705 <div class="slide">
706     <h1>Side by side</h1>
707
708     <table class="side-by-side">
709         <tr class="incremental">
710             <td>5 lines</td>
711             <td>21 lines</td>
712         </tr>
713         <tr class="incremental">
714             <td>92 characters</td>
715             <td>741 characters</td>
716         </tr>
717         <tr>
718             <td>
719                 <pre><code>package Person;
720 use Moose;
721
722 has last_name =&gt; (
723     is  =&gt; 'rw',
724     isa =&gt; 'Str',
725 );</code></pre>
726             </td>
727             <td>
728                 <pre class="small"><code>package Person;
729 use strict;
730 use warnings;
731 use Carp 'confess';
732
733 sub new {
734     my $class = shift;
735     my %args  = @_;
736     my $self  = {};
737
738     if (exists $args{last_name}) {
739         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
740                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
741             if ref($args{last_name});
742         $self-&gt;{last_nane} = $args{last_name};
743     }
744
745     return bless $self, $class;
746 }
747
748 sub last_name {
749     my $self = shift;
750
751     if (@_) {
752         my $value = shift;
753         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
754                 . &quot;Validation failed for 'Str' with value $value&quot;
755             if ref($value);
756         $self-&gt;{last_name} = $value;
757     }
758
759     return $self-&gt;{last_name};
760 }</code></pre>
761             </td>
762         </tr>
763     </table>
764 </div>
765
766 <div class="slide">
767     <h1>Typo?</h1>
768
769     <pre class="small"><code>sub new {
770     my $class = shift;
771     my %args  = @_;
772     my $self  = {};
773
774     if (exists $args{last_name}) {
775         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
776                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
777             if ref($args{last_name});
778         $self-&gt;{last_nane} = $args{last_name};
779     }
780
781     return bless $self, $class;
782 }</code></pre>
783 </div>
784
785 <div class="slide">
786     <h1>Typo?</h1>
787
788     <pre class="small"><code>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 }</code></pre>
794 </div>
795
796 <div class="slide">
797     <h1>Typo?</h1>
798
799     <code>$self-&gt;{last_nane} = $args{last_name};</code>
800 </div>
801
802 <div class="slide">
803     <h1>Typo?</h1>
804     <code>$self-&gt;{last_na<span class="highlight">n</span>e}</code>
805 </div>
806
807 <div class="slide">
808     <h1>Why Moose?</h1>
809
810     <pre><code>package Person;
811 use Moose;
812
813 has last_name =&gt; (
814     is  =&gt; 'rw',
815     isa =&gt; 'Str',
816 );</code></pre>
817 </div>
818
819 <div class="slide fake-slide0">
820   <h1>Moose Classes</h1>
821 </div>
822
823 <div class="slide">
824   <h1>Moose Classes</h1>
825
826   <ul>
827     <li>Moose classes are Perl packages which <code>use Moose</code></li>
828   </ul>
829 </div>
830
831 <div class="slide">
832   <h1>Moose.pm and Your Class</h1>
833
834   <pre><code>package Person;
835 use Moose;</code></pre>
836
837   <ul>
838     <li><code>Moose.pm</code> provides declarative sugar</li>
839     <li>Turns on <code>strict</code> and <code>warnings</code></li>
840     <li>Creates metaclasses for your class: <code>Person-&gt;meta</code></li>
841     <li>Moose classes automatically inherit from <code>Moose::Object</code></li>
842   </ul>
843 </div>
844
845 <div class="slide">
846   <h1>What <code>Moose::Object</code> Provides</h1>
847
848   <ul>
849     <li>Constructor - <code>new()</code></li>
850     <li>Calls your <code>BUILDARGS()</code> and/or <code>BUILD()</code></li>
851     <li>Calls your <code>DEMOLISH</code> during object destruction</li>
852   </ul>
853 </div>
854
855 <div class="slide">
856   <h1>extends</h1>
857
858   <ul>
859     <li><code>extends</code> is sugar for declaring parent classes</li>
860   </ul>
861
862   <pre><code>package Employee;
863 use Moose;
864 <span class="highlight">extends 'Person';</span></code></pre>
865 </div>
866
867 <div class="slide">
868   <h1>extends</h1>
869
870   <ul>
871     <li>Each call to <code>extends</code> <strong>resets</strong> your parents</li>
872   </ul>
873
874   <h2 class="wrong">WRONG</h2>
875
876   <pre><code>package EvilEmployee;
877 use Moose;
878 extends 'Person';
879 extends 'Thief';</pre></code>
880
881   <h2 class="right">RIGHT</h2>
882
883   <pre><code>package EvilEmployee;
884 use Moose;
885 extends 'Person', 'Thief';</pre></code>
886 </div>
887
888 <div class="slide">
889   <h1>Extending un-Moose-y Parents</h1>
890
891   <pre><code>package My::LWP;
892 use Moose;
893 extends 'LWP';</pre></code>
894
895   <ul>
896     <li>No <code>Moose::Object</code>, so ...
897       <ul>
898         <li>No attribute-handling <code>new()</code></li>
899         <li>No <code>BUILDARGS()</code> or <code>BUILD()</code></li>
900         <li>No <code>DEMOLISH()</code></li>
901       </ul>
902     </li>
903     <li>But see <code>MooseX::NonMoose</code> for a workaround</li>
904   </ul>
905 </div>  
906
907 <div class="slide">
908   <h1><code>overrides</code> and <code>super</code></h1>
909
910   <ul>
911     <li><code>overrides</code> is another method modifier</li>
912     <li>An alternative to Perl's <code>SUPER::</code></li>
913   </ul>
914 </div>
915
916 <div class="slide">
917   <h1><code>overrides</code> and <code>super</code></h1>
918
919   <pre><code>package Employee;
920 use Moose;
921
922 <span class="incremental current">extends 'Person';</span>
923
924 <span class="incremental">overrides</span> work =&gt; sub {
925     my $self = shift;
926
927     die "Pay me first" unless $self-&gt;got_paid;
928     <span class="incremental">super();</span>
929 }<span class="incremental">;</span></code></pre>
930
931 <div class="slide">
932   <h1>Caveat <code>super</code></h1>
933
934   <ul>
935     <li>Mostly like <code>$self-&gt;SUPER::work(@_)</code></li>
936     <li><strong>But</strong> cannot change <code>@_</code>!</li>
937     <li>Binds the parent's method at compile time</li>
938   </ul>
939 </div>
940
941 <div class="slide">
942   <h1>Attributes (Part 1)</h1>
943
944   <ul>
945     <li><code>has 'foo'</code></li>
946     <li>Use <code>is =&gt; 'ro'</code> or <code>is =&gt; 'rw'</code></li>
947     <li>Attributes without "is" have no accessors</li>
948   </ul>
949 </div>
950
951 <div class="slide">
952   <h1>Read-write attributes</h1>
953
954   <pre><code>package Person;
955 use Moose;
956
957 has 'first_name' =&gt; ( <span class="highlight">is =&gt; 'rw'</span> );
958
959 my $person =
960     Person-&gt;new( first_name =&gt; 'Dave' );
961
962 $person-&gt;first_name('Stevan');
963 print $person-&gt;first_name; # Stevan</code></pre>
964
965 </div>
966
967 <div class="slide">
968   <h1>Read-only attributes</h1>
969
970   <pre><code>package Person;
971 use Moose;
972
973 has 'first_name' =&gt; ( <span class="highlight">is =&gt; 'ro'</span> );
974
975 my $person =
976     Person-&gt;new( first_name =&gt; 'Dave' );
977
978 $person-&gt;first_name('Stevan');
979 print $person-&gt;first_name; # Dave</code></pre>
980
981 </div>
982
983 <div class="slide">
984   <h1>There is More to Come</h1>
985
986   <ul>
987     <li>Attributes have a <em>lot</em> of features</li>
988   </ul>
989 </div>
990
991 <div class="slide">
992   <h1>Cleaning Up Moose Droppings</h1>
993
994   <pre><code>package Person;
995 use Moose;
996
997 # true
998 Person->can('extends');</code></pre>
999
1000   <ul>
1001     <li>Not very hygienic</li>
1002   </ul>
1003 </div>
1004
1005 <div class="slide">
1006   <h1>Cleaning Up Moose Droppings</h1>
1007
1008   <pre><code>package Person;
1009 use Moose;
1010
1011 ...
1012
1013 no Moose;
1014
1015 # false
1016 Person->can('extends');</code></pre>
1017 </div>
1018
1019 <div class="slide">
1020   <h1>No Moose</h1>
1021
1022   <ul>
1023     <li><code>no Moose</code> at the end of a package is a best practice</li>
1024     <li>Just do it</li>
1025   </ul>
1026 </div>
1027
1028 <div class="slide">
1029   <h1>Immutability</h1>
1030
1031   <ul>
1032     <li><span style="font-family: URW Chancery L; font-size: 140%">Stevan's Incantation of Fleet-Footedness</span></li>
1033   </ul>
1034
1035   <pre><code>package Person;
1036 use Moose;
1037
1038 <span class="highlight">__PACKAGE__->meta->make_immutable;</span></code></pre>
1039 </div>
1040
1041 <div class="slide">
1042   <h1>What <code>make_immutable</code> does</h1>
1043
1044   <ul>
1045     <li>Magic</li>
1046     <li>Uses <code>eval</code> to "inline" a constructor</li>
1047     <li>Memoizes a lot of meta-information</li>
1048     <li>Makes loading your class slower</li>
1049     <li>Makes object creation <em>much</em> faster</li>
1050   </ul>
1051 </div>
1052
1053 <div class="slide">
1054   <h1>When to Immutabilize?</h1>
1055
1056   <ul>
1057     <li><em>Almost</em> always</li>
1058     <li>Startup time vs execution time</li>
1059   </ul>
1060 </div>
1061
1062 </body>
1063 </html>