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