Finished slides & exercises for section 3on basic attributes.
[gitmo/moose-presentations.git] / moose-class / slides / index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
2
3 <html xmlns="http://www.w3.org/1999/xhtml">
4
5 <head>
6 <title>Introduction to Moose</title>
7 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
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   <div id="license">
43     <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>
44     <br /><span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" property="dc:title" rel="dc:type">Introduction to Moose</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>.
45   </div>
46
47   <h2>Introduction to Moose</h2>
48 </div>
49 </div>
50
51 <div class="presentation">
52
53 <div class="slide">
54   <h1>Introduction to Moose</h1>
55   <h2>YAPC 2009</h2>
56 </div>
57
58 <div class="slide">
59   <h1>Moose Summed Up</h1>
60
61   <ul>
62     <li><strong>Declarative</strong> OO sugar</li>
63     <li>Introspectable</li>
64     <li>Extensible (MooseX::* on CPAN)</li>
65   </ul>
66 </div>
67
68 <div class="slide">
69   <h1>Moose Background</h1>
70
71   <ul>
72     <li>Created by Stevan Little, first released in 2006</li>
73     <li>Moose builds on Perl 5's native OO</li>
74     <li>Borrows ideas from other languages, notably Perl 6</li>
75     <li>Provides semantics for common operations</li>
76   </ul>
77 </div>
78
79 <div class="slide fake-slide0">
80   <h1>Part 0: Moose Concepts</h1>
81 </div>
82
83 <div class="slide">
84   <h1>Classes</h1>
85
86   <ul>
87     <li>
88       Classes have ...
89       <ul>
90         <li>Attributes</li>
91         <li>Methods</li>
92         <li>Superclasses</li>
93         <li>Method modifiers</li>
94         <li>Constructor and destructor</li>
95         <li>One metaclass object</li>
96       </ul>
97     </li>
98     <li>Classes do roles</li>
99   </ul>
100 </div>
101
102 <div class="slide">
103   <h1>Class Example</h1>
104
105   <pre><code>package Person;
106 <span class="highlight">use Moose;</span></code></pre>
107
108   <ul>
109     <li>Poof, a Moose-based class!</li>
110   </ul>
111 </div>
112
113 <div class="slide">
114   <h1>Attributes</h1>
115
116   <ul>
117     <li>Aka property, slot, field, member variable</li>
118     <li>A piece of data owned by an object</li>
119   </ul>
120 </div>
121
122 <div class="slide">
123   <h1>Attributes</h1>
124
125   <ul>
126     <li>
127       Attributes have ...
128       <ul>
129         <li>Access-control (read-only vs read-write)</li>
130         <li>An optional type</li>
131         <li>Accessor methods</li>
132         <li>Delegation methods</li>
133         <li>Optional default value</li>
134         <li>Many more features</li>
135       </ul>
136     </li>
137     <li>Stored in the object, but don't worry about that</li>
138   </ul>
139 </div>
140
141 <div class="slide">
142   <h1>Attribute Example</h1>
143
144   <pre><code>package Person;
145 use Moose;
146
147 <span class="highlight">has first_name =&gt; ( is =&gt; 'rw' );</span></code></pre>
148
149 </div>
150
151 <div class="slide">
152   <h1>Methods</h1>
153
154   <ul>
155     <li>Nothing fancy here, just Perl subroutines</li>
156   </ul>
157
158   <pre><code>package Person;
159 use Moose;
160
161 <span class="highlight">sub greet { ... }</span></code></pre>
162 </div>
163
164 <div class="slide">
165   <h1>Roles</h1>
166
167   <ul>
168     <li>Classes <strong>do</strong> (or consume) roles</li>
169     <li>Similar to mixins and Java interfaces</li>
170   </ul>
171 </div>
172
173 <div class="slide">
174   <h1>Roles</h1>
175
176   <ul>
177     <li>Like classes, can have attributes, methods, do roles</li>
178     <li>Roles can require methods</li>
179     <li>Roles are composed (flattened) into classes</li>
180   </ul>
181 </div>
182
183 <div class="slide">
184   <h1>Role Example</h1>
185
186 <pre><code>package HasPermissions;
187 <span class="highlight">use Moose::Role;</span>
188
189 has is_admin =&gt; ( is =&gt; 'rw' );</code></pre>
190 </div>
191
192 <div class="slide">
193   <h1>Role Example</h1>
194
195   <p>
196     And then ...
197   </p>
198   
199 <pre><code>package Person;
200 use Moose;
201
202 <span class="highlight">with 'HasPermissions';</span></code></pre>
203 </div>
204
205 <div class="slide">
206   <h1>Method Modifiers</h1>
207
208   <ul>
209     <li>AKA advice</li>
210     <li>&quot;<strong>Before</strong> foo(), do this first&quot;</li>
211     <li>&quot;Do this <strong>after</strong> foo()</li>
212     <li>&quot;Put this code <strong>around</strong> foo()&quot;</li>
213   </ul>
214 </div>
215
216 <div class="slide">
217   <h1>Before &amp; After</h1>
218
219 <pre><code>before 'foo'
220     =&gt; sub { warn 'About to call foo()' };
221
222 after  'foo'
223     =&gt; sub { warn 'Leaving foo()' };</code></pre>
224
225 </div>
226
227 <div class="slide">
228   <h1>Around</h1>
229
230 <pre><code>around 'foo' =&gt; sub {
231     my $real_foo = shift;
232     my $self     = shift;
233
234     warn 'Just before foo()';
235     my @return =
236         $self-&gt;$real_foo( @_, bar =&gt; 42 );
237
238     return ( @return, 'modify return values' );
239 };</code></pre>
240 </div>
241
242 <div class="slide">
243   <h1>Type Constraints</h1>
244
245   <ul>
246     <li>NOT A FULL-BLOWN TYPE SYSTEM!</li>
247     <li>But still darn useful</li>
248     <li>Constrain attribute values</li>
249     <li>Coerce from other types</li>
250   </ul>
251 </div>
252
253 <div class="slide">
254   <h1>Type Constraint Example</h1>
255
256 <pre><code>package Person;
257 use Moose;
258
259 has weight =&gt; (
260     is  =&gt; 'ro',
261     <span class="highlight">isa =&gt; 'Int'</span>,
262 );
263
264 # kaboom
265 Person-&gt;new( weight =&gt; 'fat' );</code></pre>
266 </div>
267
268 <div class="slide">
269   <h1>Delegation</h1>
270
271   <ul>
272     <li>Attributes can define delegations</li>
273     <li>Lets you hide some implementation details</li>
274     <li>Fewer objects to chase around</li>
275   </ul>
276 </div>
277
278 <div class="slide">
279   <h1>Delegation</h1>
280
281 <pre><code>package Person;
282 use Moose;
283
284 has blog_uri =&gt; (
285     is      =&gt; 'rw',
286     isa     =&gt; 'URI',
287     <span class="highlight">handles =&gt; { 'blog_hostname' =&gt; 'host' },</span>
288 );
289
290 <span class="highlight">$person->blog_hostname;</span>
291 # really calls $person->blog_uri->host</code></pre>
292 </div>
293
294 <div class="slide">
295   <h1>Constructors</h1>
296
297   <ul>
298     <li>Moose creates <code>new()</code> for you</li>
299     <li>Provide an optional <code>BUILDARGS()</code> and <code>BUILD()</code></li>
300   </ul>
301 </div>
302
303 <div class="slide">
304   <h1>Destructors</h1>
305
306   <ul>
307     <li>Provide an optional <code>DEMOLISH()</code></li>
308   </ul>
309 </div>
310
311 <div class="slide">
312   <h1>Moose Meta-API</h1>
313
314   <ul>
315     <li>Answers questions like ...
316       <ul>
317         <li>What methods does this class have?</li>
318         <li>What are its parents?</li>
319         <li>What attributes does it have (including inherited attributes)?</li>
320         <li>What roles does it do?</li>
321         <li>Much, much, more</li>
322       </ul>
323     </li>
324   </ul>
325 </div>
326
327 <div class="slide">
328   <h1>Moose Meta-API</h1>
329
330   <ul>
331     <li>Not just for introspection ...
332       <ul>
333         <li>Add methods, attributes, roles, etc</li>
334         <li>Extend and alter core features</li>
335       </ul>
336     </li>
337   </ul>
338 </div>
339
340 <div class="slide">
341   <h1>Why Moose?</h1>
342
343   <ul>
344     <li>A quick bit of propoganda ...</li>
345   </ul>
346 </div>
347
348 <div class="slide">
349   <h1>With Moose</h1>
350
351   <pre><code>package Person;
352 use Moose;
353
354 has last_name =&gt; (
355     is  =&gt; 'rw',
356     isa =&gt; 'Str',
357 );</code></pre>
358 </div>
359
360 <div class="slide">
361     <h1>Without Moose</h1>
362
363     <pre class="small"><code>package Person;
364 use strict;
365 use warnings;
366 use Carp 'confess';
367
368 sub new {
369     my $class = shift;
370     my %args  = @_;
371     my $self  = {};
372
373     if (exists $args{last_name}) {
374         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
375                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
376             if ref($args{last_name});
377         $self-&gt;{last_nane} = $args{last_name};
378     }
379
380     return bless $self, $class;
381 }
382
383 sub last_name {
384     my $self = shift;
385
386     if (@_) {
387         my $value = shift;
388         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
389                 . &quot;Validation failed for 'Str' with value $value&quot;
390             if ref($value);
391         $self-&gt;{last_name} = $value;
392     }
393
394     return $self-&gt;{last_name};
395 }</code></pre>
396
397 </div>
398
399 <div class="slide">
400     <h1>Side by side</h1>
401
402     <table class="side-by-side">
403         <tr>
404           <td>
405             <pre><code>package Person;
406 use Moose;
407
408 has last_name =&gt; (
409     is  =&gt; 'rw',
410     isa =&gt; 'Str',
411 );</code></pre>
412             </td>
413             <td>
414                 <pre class="small"><code>package Person;
415 use strict;
416 use warnings;
417 use Carp 'confess';
418
419 sub new {
420     my $class = shift;
421     my %args  = @_;
422     my $self  = {};
423
424     if (exists $args{last_name}) {
425         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
426                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
427             if ref($args{last_name});
428         $self-&gt;{last_nane} = $args{last_name};
429     }
430
431     return bless $self, $class;
432 }
433
434 sub last_name {
435     my $self = shift;
436
437     if (@_) {
438         my $value = shift;
439         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
440                 . &quot;Validation failed for 'Str' with value $value&quot;
441             if ref($value);
442         $self-&gt;{last_name} = $value;
443     }
444
445     return $self-&gt;{last_name};
446 }</code></pre>
447             </td>
448         </tr>
449     </table>
450
451 </div>
452
453 <div class="slide">
454     <h1>Side by side</h1>
455
456     <table class="side-by-side">
457         <tr>
458             <td>
459                 <pre><code><span class="match-moose">package Person;</span>
460 use Moose;
461
462 has last_name =&gt; (
463     is  =&gt; 'rw',
464     isa =&gt; 'Str',
465 );</code></pre>
466             </td>
467             <td>
468                 <pre class="small"><code><span class="match-unsweet">package Person;</span>
469 use strict;
470 use warnings;
471 use Carp 'confess';
472
473 sub new {
474     my $class = shift;
475     my %args  = @_;
476     my $self  = {};
477
478     if (exists $args{last_name}) {
479         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
480                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
481             if ref($args{last_name});
482         $self-&gt;{last_nane} = $args{last_name};
483     }
484
485     return bless $self, $class;
486 }
487
488 sub last_name {
489     my $self = shift;
490
491     if (@_) {
492         my $value = shift;
493         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
494                 . &quot;Validation failed for 'Str' with value $value&quot;
495             if ref($value);
496         $self-&gt;{last_name} = $value;
497     }
498
499     return $self-&gt;{last_name};
500 }</code></pre>
501             </td>
502         </tr>
503     </table>
504 </div>
505
506 <div class="slide">
507     <h1>Side by side</h1>
508
509     <table class="side-by-side">
510         <tr>
511             <td>
512                 <pre><code>package Person;
513 <span class="match-moose">use Moose;</span>
514
515 has last_name =&gt; (
516     is  =&gt; 'rw',
517     isa =&gt; 'Str',
518 );</code></pre>
519             </td>
520             <td>
521                 <pre class="small"><code>package Person;
522 <span class="match-unsweet">use strict;
523 use warnings;
524 use Carp 'confess';
525
526 sub new {
527     my $class = shift;
528     my %args  = @_;
529     my $self  = {};</span>
530
531     if (exists $args{last_name}) {
532         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
533                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
534             if ref($args{last_name});
535         $self-&gt;{last_nane} = $args{last_name};
536     }
537
538     <span class="match-unsweet">return bless $self, $class;
539 }</span>
540
541 sub last_name {
542     my $self = shift;
543
544     if (@_) {
545         my $value = shift;
546         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
547                 . &quot;Validation failed for 'Str' with value $value&quot;
548             if ref($value);
549         $self-&gt;{last_name} = $value;
550     }
551
552     return $self-&gt;{last_name};
553 }</code></pre>
554             </td>
555         </tr>
556     </table>
557 </div>
558
559 <div class="slide">
560     <h1>Side by side</h1>
561
562     <table class="side-by-side">
563         <tr>
564             <td>
565                 <pre><code>package Person;
566 use Moose;
567
568 <span class="match-moose">has last_name =&gt; (</span>
569     is  =&gt; 'rw',
570     isa =&gt; 'Str',
571 <span class="match-moose">);</span></code></pre>
572             </td>
573             <td>
574                 <pre class="small"><code>package Person;
575 use strict;
576 use warnings;
577 use Carp 'confess';
578
579 sub new {
580     my $class = shift;
581     my %args  = @_;
582     my $self  = {};
583
584     <span class="match-unsweet">if (exists $args{last_name}) {</span>
585         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
586                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
587             if ref($args{last_name});
588         <span class="match-unsweet">$self-&gt;{last_nane} = $args{last_name};
589     }</span>
590
591     return bless $self, $class;
592 }
593
594 sub last_name {
595     my $self = shift;
596
597     if (@_) {
598         my $value = shift;
599         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
600                 . &quot;Validation failed for 'Str' with value $value&quot;
601             if ref($value);
602         $self-&gt;{last_name} = $value;
603     }
604
605     return $self-&gt;{last_name};
606 }</code></pre>
607             </td>
608         </tr>
609     </table>
610 </div>
611
612 <div class="slide">
613     <h1>Side by side</h1>
614
615     <table class="side-by-side">
616         <tr>
617             <td>
618                 <pre><code>package Person;
619 use Moose;
620
621 has last_name =&gt; (
622     <span class="match-moose">is  =&gt; 'rw',</span>
623     isa =&gt; 'Str',
624 );</code></pre>
625             </td>
626             <td>
627                 <pre class="small"><code>package Person;
628 use strict;
629 use warnings;
630 use Carp 'confess';
631
632 sub new {
633     my $class = shift;
634     my %args  = @_;
635     my $self  = {};
636
637     if (exists $args{last_name}) {
638         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
639                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
640             if ref($args{last_name});
641         $self-&gt;{last_nane} = $args{last_name};
642     }
643
644     return bless $self, $class;
645 }
646
647 <span class="match-unsweet">sub last_name {
648     my $self = shift;
649
650     if (@_) {
651         my $value = shift;</span>
652         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
653                 . &quot;Validation failed for 'Str' with value $value&quot;
654             if ref($value);
655         <span class="match-unsweet">$self-&gt;{last_name} = $value;
656     }
657
658     return $self-&gt;{last_name};
659 }</span></code></pre>
660             </td>
661         </tr>
662     </table>
663 </div>
664
665 <div class="slide">
666     <h1>Side by side</h1>
667
668     <table class="side-by-side">
669         <tr>
670             <td>
671                 <pre><code>package Person;
672 use Moose;
673
674 has last_name =&gt; (
675     is  =&gt; 'rw',
676     <span class="match-moose">isa =&gt; 'Str',</span>
677 );</code></pre>
678             </td>
679             <td>
680                 <pre class="small"><code>package Person;
681 use strict;
682 use warnings;
683 use Carp 'confess';
684
685 sub new {
686     my $class = shift;
687     my %args  = @_;
688     my $self  = {};
689
690     if (exists $args{last_name}) {
691         <span class="match-unsweet">confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
692                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
693             if ref($args{last_name});</span>
694         $self-&gt;{last_nane} = $args{last_name};
695     }
696
697     return bless $self, $class;
698 }
699
700 sub last_name {
701     my $self = shift;
702
703     if (@_) {
704         my $value = shift;
705         <span class="match-unsweet">confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
706                 . &quot;Validation failed for 'Str' with value $value&quot;
707             if ref($value);</span>
708         $self-&gt;{last_name} = $value;
709     }
710
711     return $self-&gt;{last_name};
712 }</code></pre>
713             </td>
714         </tr>
715     </table>
716 </div>
717
718 <div class="slide">
719     <h1>Side by side</h1>
720
721     <table class="side-by-side">
722         <tr class="incremental">
723             <td>5 lines</td>
724             <td>21 lines</td>
725         </tr>
726         <tr class="incremental">
727             <td>92 characters</td>
728             <td>741 characters</td>
729         </tr>
730         <tr>
731             <td>
732                 <pre><code>package Person;
733 use Moose;
734
735 has last_name =&gt; (
736     is  =&gt; 'rw',
737     isa =&gt; 'Str',
738 );</code></pre>
739             </td>
740             <td>
741                 <pre class="small"><code>package Person;
742 use strict;
743 use warnings;
744 use Carp 'confess';
745
746 sub new {
747     my $class = shift;
748     my %args  = @_;
749     my $self  = {};
750
751     if (exists $args{last_name}) {
752         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
753                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
754             if ref($args{last_name});
755         $self-&gt;{last_nane} = $args{last_name};
756     }
757
758     return bless $self, $class;
759 }
760
761 sub last_name {
762     my $self = shift;
763
764     if (@_) {
765         my $value = shift;
766         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
767                 . &quot;Validation failed for 'Str' with value $value&quot;
768             if ref($value);
769         $self-&gt;{last_name} = $value;
770     }
771
772     return $self-&gt;{last_name};
773 }</code></pre>
774             </td>
775         </tr>
776     </table>
777 </div>
778
779 <div class="slide">
780     <h1>Typo?</h1>
781
782     <pre class="small"><code>sub new {
783     my $class = shift;
784     my %args  = @_;
785     my $self  = {};
786
787     if (exists $args{last_name}) {
788         confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
789                 . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
790             if ref($args{last_name});
791         $self-&gt;{last_nane} = $args{last_name};
792     }
793
794     return bless $self, $class;
795 }</code></pre>
796 </div>
797
798 <div class="slide">
799     <h1>Typo?</h1>
800
801     <pre class="small"><code>if (exists $args{last_name}) {
802     confess &quot;Attribute (last_name) does not pass the type constraint because: &quot;
803             . &quot;Validation failed for 'Str' with value $args{last_name}&quot;
804         if ref($args{last_name});
805     $self-&gt;{last_nane} = $args{last_name};
806 }</code></pre>
807 </div>
808
809 <div class="slide">
810     <h1>Typo?</h1>
811
812     <code>$self-&gt;{last_nane} = $args{last_name};</code>
813 </div>
814
815 <div class="slide">
816     <h1>Typo?</h1>
817     <code>$self-&gt;{last_na<span class="wrong">n</span>e}</code>
818 </div>
819
820 <div class="slide">
821     <h1>Why Moose?</h1>
822
823     <pre><code>package Person;
824 use Moose;
825
826 has last_name =&gt; (
827     is  =&gt; 'rw',
828     isa =&gt; 'Str',
829 );</code></pre>
830 </div>
831
832 <div class="slide fake-slide0">
833   <h1>Part 1: Moose Classes</h1>
834 </div>
835
836 <div class="slide">
837   <h1>Moose Classes</h1>
838
839   <ul>
840     <li>Moose classes are Perl packages which <code>use Moose</code></li>
841   </ul>
842 </div>
843
844 <div class="slide">
845   <h1>Moose.pm and Your Class</h1>
846
847   <pre><code>package Person;
848 use Moose;</code></pre>
849
850   <ul>
851     <li><code>Moose.pm</code> provides declarative sugar</li>
852     <li>Turns on <code>strict</code> and <code>warnings</code></li>
853     <li>Creates metaclasses for your class: <code>Person-&gt;meta</code></li>
854     <li>Moose classes automatically inherit from <code>Moose::Object</code></li>
855   </ul>
856 </div>
857
858 <div class="slide">
859   <h1>What <code>Moose::Object</code> Provides</h1>
860
861   <ul>
862     <li>Constructor - <code>new()</code></li>
863     <li>Calls your <code>BUILDARGS()</code> and/or <code>BUILD()</code></li>
864     <li>Calls your <code>DEMOLISH</code> during object destruction</li>
865   </ul>
866 </div>
867
868 <div class="slide">
869   <h1>extends</h1>
870
871   <ul>
872     <li><code>extends</code> is sugar for declaring parent classes</li>
873   </ul>
874
875   <pre><code>package Employee;
876 use Moose;
877 <span class="highlight">extends 'Person';</span></code></pre>
878 </div>
879
880 <div class="slide">
881   <h1>extends</h1>
882
883   <ul>
884     <li>Each call to <code>extends</code> <strong>resets</strong> your parents</li>
885   </ul>
886
887   <h2 class="wrong">WRONG</h2>
888
889   <pre><code>package EvilEmployee;
890 use Moose;
891 extends 'Person';
892 extends 'Thief';</code></pre>
893
894   <h2 class="right">RIGHT</h2>
895
896   <pre><code>package EvilEmployee;
897 use Moose;
898 extends 'Person', 'Thief';</code></pre>
899 </div>
900
901 <div class="slide">
902   <h1>Extending un-Moose-y Parents</h1>
903
904   <pre><code>package My::LWP;
905 use Moose;
906 extends 'LWP';</code></pre>
907
908   <ul>
909     <li>No <code>Moose::Object</code>, so ...
910       <ul>
911         <li>No attribute-handling <code>new()</code></li>
912         <li>No <code>BUILDARGS()</code> or <code>BUILD()</code></li>
913         <li>No <code>DEMOLISH()</code></li>
914       </ul>
915     </li>
916     <li>But see <code>MooseX::NonMoose</code> for a workaround</li>
917   </ul>
918 </div>  
919
920 <div class="slide">
921   <h1><code>overrides</code> and <code>super</code></h1>
922
923   <ul>
924     <li><code>overrides</code> is another method modifier</li>
925     <li>An alternative to Perl's <code>SUPER::</code></li>
926   </ul>
927 </div>
928
929 <div class="slide">
930   <h1><code>overrides</code> and <code>super</code></h1>
931
932   <pre><code>package Employee;
933 use Moose;
934
935 <span class="current">extends 'Person';</span>
936
937 <span class="incremental">overrides</span> work =&gt; sub {
938     my $self = shift;
939
940     die "Pay me first" unless $self-&gt;got_paid;
941     <span class="incremental">super();</span>
942 }<span class="incremental">;</span></code></pre>
943 </div>
944
945 <div class="slide">
946   <h1>Caveat <code>super</code></h1>
947
948   <ul>
949     <li>Mostly like <code>$self-&gt;SUPER::work(@_)</code></li>
950     <li><strong>But</strong> cannot change <code>@_</code>!</li>
951     <li>Binds the parent's method at compile time</li>
952   </ul>
953 </div>
954
955 <div class="slide">
956   <h1>Attributes (Part 1)</h1>
957
958   <ul>
959     <li><code>has 'foo'</code></li>
960     <li>Use <code>is =&gt; 'ro'</code> or <code>is =&gt; 'rw'</code></li>
961     <li>Attributes without "is" have no accessors</li>
962   </ul>
963 </div>
964
965 <div class="slide">
966   <h1>Read-write attributes</h1>
967
968   <pre><code>package Person;
969 use Moose;
970
971 has first_name =&gt; ( <span class="highlight">is =&gt; 'rw'</span> );
972
973 my $person =
974     Person-&gt;new( first_name =&gt; 'Dave' );
975
976 $person-&gt;first_name('Stevan');
977 print $person-&gt;first_name; # Stevan</code></pre>
978
979 </div>
980
981 <div class="slide">
982   <h1>Read-only attributes</h1>
983
984   <pre><code>package Person;
985 use Moose;
986
987 has first_name =&gt; ( <span class="highlight">is =&gt; 'ro'</span> );
988
989 my $person =
990     Person-&gt;new( first_name =&gt; 'Dave' );
991
992 $person-&gt;first_name('Stevan');
993 print $person-&gt;first_name; # Dave</code></pre>
994
995 </div>
996
997 <div class="slide">
998   <h1>There is More to Come</h1>
999
1000   <ul>
1001     <li>Attributes have a <em>lot</em> of features</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 # true
1012 Person->can('extends');</code></pre>
1013
1014   <ul>
1015     <li>Not very hygienic</li>
1016   </ul>
1017 </div>
1018
1019 <div class="slide">
1020   <h1>Cleaning Up Moose Droppings</h1>
1021
1022   <pre><code>package Person;
1023 use Moose;
1024
1025 ...
1026
1027 no Moose;
1028
1029 # false
1030 Person->can('extends');</code></pre>
1031 </div>
1032
1033 <div class="slide">
1034   <h1>No Moose</h1>
1035
1036   <ul>
1037     <li><code>no Moose</code> at the end of a package is a best practice</li>
1038     <li>Just do it</li>
1039   </ul>
1040 </div>
1041
1042 <div class="slide">
1043   <h1>Immutability</h1>
1044
1045   <ul>
1046     <li><span style="font-family: URW Chancery L; font-size: 140%">Stevan's Incantation of Fleet-Footedness</span></li>
1047   </ul>
1048
1049   <pre><code>package Person;
1050 use Moose;
1051
1052 <span class="highlight">__PACKAGE__->meta->make_immutable;</span></code></pre>
1053 </div>
1054
1055 <div class="slide">
1056   <h1>What <code>make_immutable</code> does</h1>
1057
1058   <ul>
1059     <li>Magic</li>
1060     <li>Uses <code>eval</code> to "inline" a constructor</li>
1061     <li>Memoizes a lot of meta-information</li>
1062     <li>Makes loading your class slower</li>
1063     <li>Makes object creation <em>much</em> faster</li>
1064   </ul>
1065 </div>
1066
1067 <div class="slide">
1068   <h1>When to Immutabilize?</h1>
1069
1070   <ul>
1071     <li><em>Almost</em> always</li>
1072     <li>Startup time vs execution time</li>
1073   </ul>
1074 </div>
1075
1076 <div class="slide">
1077   <h1>Classes Summary</h1>
1078
1079   <ul>
1080     <li><code>use Moose</code></li>
1081     <li><code>Class-&gt;meta</code></li>
1082     <li><code>Moose::Object</code> base class</li>
1083     <li><code>extends</code>, <code>overrides</code>, and <code>super</code></li>
1084     <li>Simple attributes: <code>has</code>, <code>is&nbsp;=&gt;&nbsp;'ro'</code>, &amp; <code>is&nbsp;=&gt;&nbsp;'rw'</code></li>
1085     <li><code>no Moose</code></li>
1086     <li><code>__PACKAGE__-&gt;meta-&gt;make_immutable</code></li>
1087   </ul>
1088 </div>
1089
1090 <div class="slide">
1091   <h1>Exercises</h1>
1092
1093   <pre># cd exercises
1094 $ perl bin/prove -lv t/00-prereq.t
1095
1096 Missing anything? Install it. (see tarballs/)
1097
1098 # perl bin/prove -lv t/01-classes.t
1099
1100 Iterate til this passes all its tests</pre>
1101 </div>
1102
1103 <div class="slide fake-slide0">
1104   <h1>Part 2: Roles</h1>
1105 </div>
1106
1107 <div class="slide">
1108   <h1>Just What Is a Role?</h1>
1109
1110   <ul>
1111     <li>Mixin? Interface? Trait?</li>
1112     <li>Yes ... and more!</li>
1113   </ul>
1114 </div>
1115
1116 <div class="slide">
1117   <h1>Roles Can Have State <strong>and</strong> Behavior</h1>
1118
1119   <pre><code>package HasPermissions;
1120 use Moose::Role;
1121
1122 <span class="current"># state
1123 has access_level =&gt; ( is =&gt; 'rw' );</span>
1124
1125 <span class="incremental"># behavior
1126 sub can_access {
1127     my $self     = shift;
1128     my $required = shift;
1129
1130     return $self-&gt;access_level &gt;= $required;
1131 }</span></code></pre>
1132
1133 </div>
1134
1135 <div class="slide">
1136   <h1>Roles Can Define Interfaces</h1>
1137
1138   <pre><code>package Printable;
1139 use Moose::Role;
1140
1141 requires 'as_string';</code></pre>
1142 </div>
1143
1144 <div class="slide">
1145   <h1>Roles Can Do All Three</h1>
1146
1147   <pre><code>package Printable;
1148 use Moose::Role;
1149
1150 requires 'as_string';
1151
1152 has has_been_printed =&gt; ( is =&gt; 'rw'  );
1153
1154 sub print {
1155     my $self = shift;
1156     print $self-&gt;as_string;
1157     $self-&gt;has_been_printed(1);
1158 }</code></pre>
1159 </div>
1160
1161 <div class="slide">
1162   <h1>Classes Consume Roles</h1>
1163
1164   <pre><code>package Person;
1165 use Moose;
1166
1167 with 'HasPermissions';</code></pre>
1168 </div>
1169
1170 <div class="slide">
1171   <h1>Classes Consume Roles</h1>
1172
1173 <pre><code>my $person = Person-&gt;new(
1174     first_name => 'Kenichi',
1175     last_name => 'Asai',
1176     access_level =&gt; 42,
1177 );
1178
1179 print $person-&gt;full_name
1180     . ' has '
1181     . $person-&gt;can_access(42)
1182         ? 'great power'
1183         : 'little power';</code></pre>
1184 </div>
1185
1186 <div class="slide">
1187   <h1>Roles in Practice</h1>
1188
1189   <ul>
1190     <li>Consuming a role =~ inlining the role</li>
1191   </ul>
1192 </div>
1193
1194 <div class="slide">
1195   <h1>In Other Words ...</h1>
1196
1197 <pre><code>package Person;
1198 use Moose;
1199
1200 <span class="highlight">with 'Printable';</span></code></pre>
1201 </div>
1202
1203 <div class="slide">
1204   <h1>In Other Words ...</h1>
1205
1206 <pre><code>package Person;
1207 use Moose;
1208
1209 <span class="delete">with 'Printable';</span>
1210
1211 <span class="highlight">has has_been_printed =&gt; ( is =&gt; 'rw'  );
1212
1213 sub print {
1214     my $self = shift;
1215     print $self-&gt;as_string;
1216     $self-&gt;has_been_printed(1);
1217 }</span></code></pre>
1218 </div>
1219
1220 <div class="slide">
1221   <h1>Except</h1>
1222
1223   <ul>
1224     <li>Role consumption is introspectable</li>
1225   </ul>
1226
1227   <pre><code>if ( Person-&gt;does('Printable') ) { ... }
1228
1229 # or ...
1230
1231 if ( Person-&gt;meta-&gt;does('Printable') ) { ... }</code></pre>
1232
1233 </div>
1234
1235 <div class="slide">
1236   <h1>These Names Are the Same</h1>
1237
1238   <ul>
1239     <li>What if a role and class define the same method?</li>
1240     <li>A class's <em>local</em> methods win over the role's</li>
1241     <li>The role's methods win over the class's <em>inherited</em> methods</li>
1242   </ul>
1243 </div>
1244
1245 <div class="slide">
1246   <h1>Conflicts Between Roles</h1>
1247
1248   <ul>
1249     <li>Two roles with a method of the same name</li>
1250     <li>Generates a compile-time error when consumed by a class</li>
1251   </ul>
1252 </div>
1253
1254 <div class="slide">
1255   <h1>Conflict Example</h1>
1256
1257   <pre><code>package IsFragile;
1258 use Moose::Role;
1259
1260 sub break { ... }
1261
1262 package CanBreakdance;
1263 use Moose::Role;
1264
1265 sub break { ... }</code></pre>
1266 </div>
1267
1268 <div class="slide">
1269   <h1>Conflict Example</h1>
1270
1271   <pre><code>package FragileDancer;
1272 use Moose;
1273
1274 <span class="highlight">with 'IsFragile', 'CanBreakdance';</span></code></pre>
1275
1276   <ul>
1277     <li>Only one <code>with</code>!</li>
1278   </ul>
1279 </div>
1280
1281 <div class="slide">
1282   <h1>Conflict Resolution</h1>
1283
1284   <ul>
1285     <li>The consuming class must resolve the conflict by implementing th emethod</li>
1286     <li>Can use some combination of method exclusion and aliasing</li>
1287   </ul>
1288 </div>
1289
1290 <div class="slide">
1291   <h1>Method Aliasing</h1>
1292
1293   <pre><code>package FragileDancer;
1294 use Moose;
1295
1296 <span class="highlight">with 'IsFragile' =>
1297          { alias =>
1298                { break => 'break_bone' } },
1299      'CanBreakdance' =>
1300          { alias =>
1301                { break => 'break_it_down' } };</span></code></pre>
1302
1303   <ul>
1304     <li>Renames the roles' methods</li>
1305     <li>Still conflicts, need to <code>exclude</code> as well</li>
1306   </ul>
1307 </div>
1308
1309 <div class="slide">
1310   <h1>Method Exclusion</h1>
1311
1312   <pre><code>package FragileDancer;
1313 use Moose;
1314
1315 <span class="highlight">with 'IsFragile' =>
1316          { alias =>
1317                { break => 'break_bone' },
1318            exclude => 'break' },
1319      'CanBreakdance' =>
1320          { alias =>
1321                { break => 'break_dance' },
1322            exclude => 'break' };</span></code></pre>
1323 </div>
1324
1325 <div class="slide">
1326   <h1>And then ...</h1>
1327
1328   <pre><code>package FragileDancer;
1329 use Moose;
1330
1331 sub break {
1332     my $self = shift;
1333
1334     $self->break_dance;
1335     if ( rand(1) &lt; 0.5 ) {
1336         $self->break_bone;
1337     }
1338 }</code></pre>
1339 </div>
1340
1341 <div class="slide">
1342   <h1>Still Full of Fail</h1>
1343
1344   <ul>
1345     <li>Roles are also about semantics!</li>
1346     <li>We've fulfilled the letter and lost the spirit</li>
1347     <li>Roles have a <em>meaning</em></li>
1348     <li>Think twice before blindly aliasing and excluding methods!</li>
1349   </ul>
1350 </div>
1351
1352 <div class="slide">
1353   <h1>Hot Role-on-Role Action</h1>
1354
1355   <pre><code>package Comparable;
1356 use Moose::Role;
1357
1358 requires 'compare';</code></pre>
1359 </div>
1360
1361 <div class="slide">
1362   <h1>Hot Role-on-Role Action</h1>
1363
1364   <pre><code>package TestsEquality;
1365 use Moose::Role;
1366
1367 with 'Comparable';
1368
1369 sub is_equal {
1370     my $self = shift;
1371     return $self->compare(@_) == 0;
1372 }</code></pre>
1373 </div>
1374
1375 <div class="slide">
1376   <h1>And then ...</h1>
1377
1378   <pre><code>package Integer;
1379 use Moose;
1380
1381 with 'TestsEquality';
1382
1383 # Satisfies the Comparable role
1384 sub compare { ... }
1385
1386 Integer->does('TestsEquality'); # true
1387 Integer->does('Comparable'); # also true!</code></pre>
1388 </div>
1389
1390 <div class="slide">
1391   <h1>Name Conflicts Between Roles</h1>
1392
1393   <pre><code>package HasSubProcess;
1394 use Moose::Role;
1395
1396 <span class="highlight">sub execute { ... }</span>
1397
1398 package Killer;
1399 use Moose::Role;
1400
1401 with 'HasSubProcess';
1402
1403 <span class="highlight">sub execute { ... }</span></code></pre>
1404 </div>
1405
1406 <div class="slide">
1407   <h1>Delayed Conflict</h1>
1408
1409   <pre><code>package StateOfTexas;
1410 with 'Killer';</code></pre>
1411
1412   <ul>
1413     <li><code>StateOfTexas</code> must implement its own <code>execute</code></li>
1414     <li>But loading the <code>Killer</code> role by itself does not cause an error</li>
1415   </ul>
1416 </div>
1417
1418 <div class="slide">
1419   <h1>Roles as Interfaces</h1>
1420
1421   <ul>
1422     <li>Roles can <code>require</code> methods of their consumers</li>
1423     <li>Compile-time checks</li>
1424     <li>Method must exist when the role is consumed</li>
1425   </ul>
1426 </div>
1427
1428 <div class="slide">
1429   <h1>The Attribute Gotcha</h1>
1430
1431 <pre><code>package HasSize;
1432 use Moose::Role;
1433
1434 <span class="current">requires 'size';</span>
1435
1436 package Shirt;
1437 use Moose;
1438
1439 <span class="incremental">with 'HasSize';
1440
1441 has size => ( is => 'ro' );</span></code></pre>
1442 </div>
1443
1444 <div class="slide">
1445   <h1>The Attribute Gotcha Workaround</h1>
1446
1447   <pre><code>package HasSize;
1448 use Moose::Role;
1449
1450 requires 'size';
1451
1452 package Shirt;
1453 use Moose;
1454
1455 has size => ( is => 'ro' );
1456
1457 with 'HasSize';</code></pre>
1458 </div>
1459
1460 <div class="slide">
1461   <h1>Compile-time Is a Lie</h1>
1462
1463   <ul>
1464     <li>Really, it's <em>package load</em> time</li>
1465     <li>That's run-time, but before the "real" run-time</li>
1466     <li>Moose does not rewire Perl, it's just sugar!</li>
1467     <li>(but <code>MooseX::Declare</code> <em>does</em> rewire Perl)</li>
1468   </ul>
1469 </div>
1470
1471 <div class="slide">
1472   <h1>Enforcing Roles</h1>
1473
1474   <pre><code>package Comparison;
1475 use Moose;
1476
1477 has [ 'left', 'right' ] => (
1478     is   => 'ro',
1479     <span class="highlight">does => 'Comparable',</span>
1480 );
1481 </code></pre>
1482
1483   <ul>
1484     <li>A sneak peek at type constraints</li>
1485   </ul>
1486 </div>
1487
1488
1489 <div class="slide">
1490   <h1>Roles Can Be Applied to Objects</h1>
1491
1492   <pre><code>use Moose::Util qw( apply_all_roles );
1493
1494 my $fragile_person = Person->new( ... );
1495 apply_all_roles( $fragile_person, 'IsFragile' );</code></pre>
1496
1497   <ul>
1498     <li>Does not change the <code>Person</code> class</li>
1499     <li>Works with non-Moose classes, great for monkey-patching!</li>
1500   </ul>
1501 </div>
1502
1503 <div class="slide">
1504   <h1>Roles Are Dirty Too</h1>
1505
1506   <ul>
1507     <li>Once again, clean up those Moose droppings</li>
1508   </ul>
1509
1510   <pre><code>package Comparable;
1511 use Moose::Role;
1512
1513 requires 'compare';
1514
1515 <span class="highlight">no Moose::Role;</span></code></pre>
1516
1517   <ul>
1518     <li>But roles cannot be made immutable</li>
1519   </ul>
1520 </div>
1521
1522 <div class="slide">
1523   <h1>The Zen of Roles</h1>
1524
1525   <ul>
1526     <li>Roles represent discrete units of ...
1527       <ul>
1528         <li>state</li>
1529         <li>behavior</li>
1530         <li>interface</li>
1531       </ul>
1532     </li>
1533     <li>Roles are shareable between unrelated classes</li>
1534     <li>Roles are what a class <em>does</em>, not what it <em>is</em></li>
1535     <li>Roles <em>add</em> functionality, inheritance <em>specializes</em></li>
1536   </ul>
1537 </div>
1538
1539 <div class="slide">
1540   <h1>Abstract Examples</h1>
1541
1542   <ul>
1543     <li>Human <em>@ISA</em> Animal</li>
1544     <li>Human <em>does</em> Toolmaker (as <em>does</em> Chimpanzee)</li>
1545     <li>Car <em>@ISA</em> Vehicle</li>
1546     <li>Car <em>does</em> HasEngine</li>
1547   </ul>
1548 </div>
1549
1550 <div class="slide">
1551   <h1>Real Examples</h1>
1552
1553   <ul>
1554     <li>Objects representing SQL database components and queries
1555       <ul>
1556         <li>Schema, Table, Column, ColumnAlias</li>
1557         <li>Select, Insert, Update, Delete</li>
1558       </ul>
1559     </li>
1560   </ul>
1561 </div>
1562
1563 <div class="slide">
1564   <h1>Real Examples</h1>
1565
1566   <ul>
1567     <li>Column and ColumnAlias both <em>do</em> ColumnLike</li>
1568     <li>ColumnLike things can be used in certain parts of queries</li>
1569     <li>All queries <em>do</em> HasWhereClause</li>
1570     <li>Select <em>does</em> Comparable and Selectable (for subselects)</li>
1571     <li>A where clause requires its components to <em>do</em> Comparable</li>
1572   </ul>
1573 </div>
1574
1575 <div class="slide">
1576   <h1>Exercises</h1>
1577
1578   <pre># cd exercises
1579 # perl bin/prove -lv t/02-roles.t
1580
1581 Iterate til this passes all its tests</pre>
1582 </div>
1583
1584 <div class="slide fake-slide0">
1585   <h1>Part 3: Basic Attributes</h1>
1586 </div>
1587
1588 <div class="slide">
1589   <h1>Attributes Are Huge</h1>
1590
1591   <ul>
1592     <li>Moose's biggest feature</li>
1593     <li>The target of <em>many</em> MooseX modules</li>
1594   </ul>
1595 </div>
1596
1597 <div class="slide">
1598   <h1>Quick Review</h1>
1599
1600   <ul>
1601     <li>Declared with <code>has</code></li>
1602     <li>Read-only or read-write</li>
1603   </ul>
1604
1605   <pre><code>package Shirt;
1606 use Moose;
1607
1608 has 'color'     =&gt; ( is =&gt; 'ro' );
1609 has 'is_ripped' =&gt; ( is =&gt; 'rw' );</code></pre>
1610 </div>
1611
1612 <div class="slide">
1613   <h1>Required-ness</h1>
1614
1615   <ul>
1616     <li>Required means "must be passed to the constructor"</li>
1617     <li>But can be <code>undef</code></li>
1618   </ul>
1619 </div>
1620
1621 <div class="slide">
1622   <h1>Required-ness</h1>
1623
1624   <pre><code>package Person;
1625 use Moose;
1626
1627 has first_name =&gt; (
1628     is       =&gt; 'ro',
1629     <span class="current">required =&gt; 1,</span>
1630 );
1631
1632 <span class="incremental">Person->new( first_name =&gt; undef ); # ok
1633 Person->new(); # kaboom</span></code></pre>
1634 </div>
1635
1636 <div class="slide">
1637   <h1>Default and Builder</h1>
1638
1639   <ul>
1640     <li>Attributes can have defaults</li>
1641     <li>Simple non-referecne scalars (number, string)</li>
1642     <li>Subroutine reference</li>
1643     <li>A builder method</li>
1644   </ul>
1645 </div>
1646
1647 <div class="slide">
1648   <h1>Default</h1>
1649
1650   <ul>
1651     <li>Can be a non-reference scalar (including <code>undef</code>)</li>
1652   </ul>
1653
1654   <pre><code>package Person;
1655 use Moose;
1656
1657 has bank =&gt; (
1658     is      =&gt; 'rw',
1659     default =&gt; 'Spire FCU',
1660 );</code></pre>
1661 </div>
1662
1663 <div class="slide">
1664   <h1>Default</h1>
1665
1666   <ul>
1667     <li>Can be a subroutine reference</li>
1668   </ul>
1669
1670   <pre><code>package Person;
1671 use Moose;
1672
1673 has bank =&gt; (
1674     is      =&gt; 'rw',
1675     default =&gt;
1676         sub { Bank-&gt;new(
1677                   name =&gt; 'Spire FCU' ) },
1678 );</code></pre>
1679 </div>
1680
1681 <div class="slide">
1682   <h1>Default as a Subroutine Reference</h1>
1683
1684   <ul>
1685     <li>Called as a method on the object</li>
1686     <li>Called anew for each object</li>
1687   </ul>
1688 </div>
1689
1690 <div class="slide">
1691   <h1>Why No Other Reference Types?</h1>
1692
1693   <pre><code>package Person;
1694 use Moose;
1695
1696 has bank =&gt; (
1697     is      =&gt; 'rw',
1698     <span class="wrong">default =&gt; Bank-&gt;new(
1699                    name =&gt; 'Spire FCU' ),</span>
1700 );</code></pre>
1701
1702   <ul>
1703     <li>Now <strong>every</strong> person shares the <strong>same</strong> Bank object!</li>
1704   </ul>
1705 </div>
1706
1707 <div class="slide">
1708      <h1>Defaulting to an Empty Reference</h1>
1709
1710   <pre><code>package Person;
1711 use Moose;
1712
1713 has packages =&gt; (
1714     is      =&gt; 'rw',
1715     default =&gt; <span class="highlight">sub { [] }</span>,
1716 );</code></pre>
1717 </div>
1718
1719 <div class="slide">
1720   <h1>What if I Want to Share?</h1>
1721
1722   <pre><code>package Person;
1723 use Moose;
1724
1725 my $highlander_bank =
1726     Bank-&gt;new( name =&gt; 'Spire FCU' );
1727
1728 has bank =&gt; (
1729     is      =&gt; 'rw',
1730     default =&gt; sub { $highlander_bank },
1731 );</code></pre>
1732 </div>
1733
1734 <div class="slide">
1735   <h1>Builder</h1>
1736
1737   <ul>
1738     <li>A method <em>name</em> which returns the default</li>
1739   </ul>
1740 </div>
1741
1742 <div class="slide">
1743   <h1>Builder</h1>
1744
1745   <pre><code>package Person;
1746 use Moose;
1747
1748 has bank =&gt; (
1749     is      =&gt; 'rw',
1750     builder =&gt; '_build_bank',
1751 );
1752
1753 sub _build_bank {
1754     my $self = shift;
1755     return Bank-&gt;new( name => 'Spire FCU' );
1756 }</code></pre>
1757 </div>
1758
1759 <div class="slide">
1760   <h1>Default vs Builder</h1>
1761
1762   <ul>
1763     <li>Use default for simple scalars</li>
1764     <li>Use default to return empty references</li>
1765     <li>Use default for <em>very</em> trivial subroutine references</li>
1766     <li>Use builder for everything else</li>
1767   </ul>
1768 </div>
1769
1770 <div class="slide">
1771   <h1>Builder Bonuses</h1>
1772
1773   <ul>
1774     <li>Can be overridden and method modified, because it's called by <em>name</em></li>
1775     <li>Roles can require a builder</li>
1776   </ul>
1777 </div>
1778       
1779 <div class="slide">
1780   <h1>Role Requires Builder</h1>
1781
1782   <pre><code>package HasBank;
1783 use Moose::Role;
1784
1785 requires '_build_bank';
1786
1787 has bank =&gt; (
1788     is      =&gt; 'ro',
1789     builder =&gt; '_build_bank',
1790 );</code></pre>
1791 </div>
1792
1793 <div class="slide">
1794   <h1>Lazy, Good for Nothing Attributes</h1>
1795
1796   <ul>
1797     <li>Normally, defaults are generated during object construction</li>
1798     <li>This can be expensive</li>
1799     <li>We want to default to <code>$self-&gt;size * 2</code>, but attribute initialization order is unpredictable</li>
1800     <li>Use lazy attributes!</li>
1801   </ul>
1802 </div>
1803
1804 <div class="slide">
1805   <h1>The Power of Dynamic Defaults</h1>
1806
1807   <pre><code>package Person;
1808 use Moose;
1809
1810 has shoe_size =&gt; (
1811     is =&gt; 'ro',
1812 );</code></pre>
1813 </div>
1814
1815 <div class="slide">
1816   <h1>The Power of Dynamic Defaults</h1>
1817
1818   <pre><code>has shoes =&gt; (
1819     is      =&gt; 'ro',
1820     <span class="highlight">lazy    =&gt; 1,</span>
1821     builder => '_build_shoes',
1822 );
1823
1824 sub _build_shoes {
1825     my $self = shift;
1826
1827     return Shoes-&gt;new(
1828         size =&gt; <span class="highlight">$_[0]-&gt;shoe_size</span> );
1829 }</code></pre>
1830 </div>
1831
1832 <div class="slide">
1833   <h1>Lazy is Good</h1>
1834
1835   <ul>
1836     <li>Lazy defaults are executed when the attribute is read</li>
1837     <li>Can see other object attributes</li>
1838     <li>Still need to watch out for circular laziness</li>
1839   </ul>
1840 </div>    
1841
1842 <div class="slide">
1843   <h1>Clearer and Predicate</h1>
1844
1845   <ul>
1846     <li>Attributes can have a value, including <code>undef</code>, or not</li>
1847     <li>Can clear the value with a clearer method</li>
1848     <li>Can check for the existence of a value with a predicate method</li>
1849     <li>By default, these methods are not created</li>
1850   </ul>
1851 </div>
1852
1853 <div class="slide">
1854   <h1>Clearer and Predicate</h1>
1855
1856   <pre><code>package Person;
1857 use Moose;
1858
1859 has account =&gt; (
1860     is        =&gt; 'ro',
1861     lazy      =&gt; 1,
1862     builder   =&gt; '_build_account',
1863     <span class="highlight">clearer   =&gt; '_clear_account',
1864     predicate =&gt; 'has_account',</span>
1865 );</code></pre>
1866 </div>
1867
1868 <div class="slide">
1869   <h1>Clearer and Lazy Defaults</h1>
1870
1871   <ul>
1872     <li>Lazy defaults are good for computed attributes</li>
1873     <li>Clear the attribute when the source data changes</li>
1874     <li>Recalculated at next access</li>
1875   </ul>
1876 </div>
1877
1878 <div class="slide">
1879   <h1>Renaming constructor arguments</h1>
1880
1881   <ul>
1882     <li>By default, constructor names = attribute names</li>
1883     <li>Use <code>init_arg</code> to change this</li>
1884     <li>Set <code>init_arg =&gt; undef</code> to make it unconstructable</li>
1885   </ul>
1886 </div>
1887
1888 <div class="slide">
1889   <h1>Some <code>init_arg</code> examples</h1>
1890
1891   <pre><code>package Person;
1892 use Moose;
1893
1894 has shoe_size => (
1895     is       =&gt; 'ro',
1896     <span class="highlight">init_arg =&gt; 'foot_size',</span>
1897 );
1898
1899 Person->new( <span class="wrong">shoe_size =&gt; 13</span> );
1900
1901 my $person =
1902     Person->new( <span class="right">foot_size =&gt; 13</span> );
1903 print $person->shoe_size;</code></pre>
1904 </div>
1905
1906 <div class="slide">
1907   <h1>Some <code>init_arg</code> examples</h1>
1908
1909 <pre><code>package Person;
1910 use Moose;
1911
1912 has shoes => (
1913     is       =&gt; 'ro',
1914     <span class="highlight">init_arg =&gt; undef,</span>
1915 );
1916
1917 Person->new( <span class="wrong">shoes =&gt; Shoes-&gt;new</span> );</code></pre>
1918 </div>
1919
1920 <div class="slide">
1921   <h1>Why Set <code>init_arg =&gt; undef</code>?</h1>
1922
1923   <ul>
1924     <li>Use this with a lazy default for attributes-as-cache</li>
1925     <li>Compute the value as needed</li>
1926     <li>Ensure that it is always generated correctly (not set by constructor)</li>
1927     <li>Use triggers or method modifiers (coming soon) to clear the value</li>
1928   </ul>
1929 </div>
1930
1931 <div class="slide">
1932   <h1>Attribute Inheritance</h1>
1933
1934   <ul>
1935     <li>By default, subclasses inherit attribute as-is</li>
1936     <li>Can change some attribute parameters in subclasses
1937       <ul>
1938         <li>default</li>
1939         <li>builder</li>
1940         <li>required</li>
1941         <li>lazy</li>
1942         <li>others we've not yet covered</li>
1943       </ul>
1944     </li>
1945   </ul>
1946 </div>   
1947
1948 <div class="slide">
1949   <h1>Attribute Inheritance Example</h1>
1950
1951   <pre><code>package Employee;
1952 use Moose;
1953
1954 extends 'Person';
1955
1956 has '<span class="highlight">+first_name</span>' =&gt; (
1957     default =&gt; 'Joe',
1958 );</code></pre>
1959 </div>
1960
1961 <div class="slide">
1962   <h1>Attribute Inheritance Warning</h1>
1963
1964   <ul>
1965     <li>An attribute is a contract about a class's API</li>
1966     <li>Don't break that contract in a subclass</li>
1967     <li>Especially important in the context of types</li>
1968   </ul>
1969 </div>
1970
1971 <div class="slide">
1972   <h1>Changing Accessor Names</h1>
1973
1974   <pre><code>package Person;
1975 use Moose;
1976
1977 has first_name =&gt; (
1978     <span class="highlight">reader</span> =&gt; 'first_name',
1979     <span class="highlight">writer</span> =&gt; 'first_name',
1980 );</code></pre>
1981
1982   <ul>
1983     <li>The long-hand version of <code>is =&gt; 'rw'</code></li>
1984   </ul>
1985 </div>
1986
1987 <div class="slide">
1988   <h1>Changing Accessor Names</h1>
1989
1990   <pre><code>package Person;
1991 use Moose;
1992
1993 has first_name =&gt; (
1994     <span class="highlight">reader</span> =&gt; 'first_name',
1995     <span class="highlight">writer</span> =&gt; undef,
1996 );</code></pre>
1997
1998   <ul>
1999     <li>The long-hand version of <code>is =&gt; 'ro'</code></li>
2000   </ul>
2001 </div>
2002
2003
2004 <div class="slide">
2005   <h1>Changing Accessor Names</h1>
2006
2007   <pre><code>package Person;
2008 use Moose;
2009
2010 has first_name =&gt; (
2011     <span class="highlight">reader</span> =&gt; 'get_first_name',
2012     <span class="highlight">writer</span> =&gt; 'set_first_name,
2013 );</code></pre>
2014 </div>
2015
2016 <div class="slide">
2017   <h1>Changing Accessor Names</h1>
2018
2019   <pre><code>package Person;
2020 use Moose;
2021
2022 has first_name =&gt; (
2023     <span class="highlight">is</span>     =&gt; 'rw',
2024     <span class="highlight">writer</span> =&gt; '_first_name',
2025 );</code></pre>
2026
2027   <ul>
2028     <li>Can also mix-and-match</li>
2029   </ul>
2030 </div>
2031
2032 <div class="slide">
2033   <h1>ETOOMUCHTYPING</h1>
2034
2035   <ul>
2036     <li><code>MooseX::FollowPBP</code><br /><code>get_foo</code> and <code>set_foo</code></li>
2037     <li><code>MooseX::SemiAffordanceAccessor</code><br /><code>foo</code> and <code>set_foo</code></li>
2038   </ul>
2039 </div>
2040
2041 <div class="slide">
2042   <h1>ETOOMUCHTYPING</h1>
2043
2044   <pre><code>package Person;
2045 use Moose;
2046 <span class="highlight">use MooseX::SemiAffordanceAccessor;</span>
2047
2048 has first_name =&gt; (
2049     is =&gt; 'rw',
2050 );</code></pre>
2051
2052   <ul>
2053     <li>Creates <code>first_name</code> and <code>set_first_name</code></li>
2054   </ul>
2055 </div>
2056
2057 <div class="slide">
2058   <h1>Exercises</h1>
2059
2060   <pre># cd exercises
2061 # perl bin/prove -lv t/03-basic-attributes.t
2062
2063 Iterate til this passes all its tests</pre>
2064 </div>
2065
2066 </div> 
2067 </body>
2068 </html>
2069
2070 <!--
2071
2072 Copyright 2009 David Rolsky. All Rights Reserved.
2073
2074 This work is licensed under a Creative Commons Attribution-Share Alike
2075 3.0 United States License See
2076 http://creativecommons.org/licenses/by-sa/3.0/us/ for details.
2077
2078 -->
2079