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