cec8138c2f7cf5007f81015f26c2c14503b3a66a
[gitmo/moose-website.git] / Moose_YAPC_Asia_2008 / practical_moose.html
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;}
29 img#me01 {top: 0; left: 0;}
30 img#me02 {left: 23px;}
31 img#me04 {top: 44px;}
32 img#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>
109 package Person;
110
111 use strict;
112 use warnings;
113
114 sub new {
115     my ( $class, @args ) = @_;
116
117     @args = %{$args[0]} if @args == 1;
118
119     return bless {
120         @args,
121     }, $class;
122 }
123
124 sub name {
125     my ($self, @args) = @_;
126     $self->{name} = $args[0] if @args;
127     return $self->{name};
128 }
129
130 sub age {
131     my ($self, @args) = @_;
132     $self->{age} = $args[0] if @args;
133     return $self->{age}; 
134 }
135
136 1;
137 </code></pre>
138
139 </div>
140
141 <div class="slide">
142 <h1>A Simple Moose Example</h1>
143
144 <pre><code>
145 package Person;
146 use Moose;
147
148 has name => (is => 'rw');
149 has age  => (is => 'rw');
150
151 1;
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>
194 package Manager;
195 use Moose;
196
197 has name => (
198     is  => 'rw',
199     isa => 'Str',
200     default => 'Bob'
201 );
202
203 has 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>
294 package Employee;
295 use Moose;
296 extends qw(Person);
297
298 has 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>
321 has 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>
333 has 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>
346 has 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>
358 package Company;
359 use Moose;
360 use MooseX::AttributeHelpers;
361
362 has 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>
381 before 'employees' => sub { warn 'calling employees' };
382
383 after '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>
400 around '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>
415 package Employee;
416 use Moose;
417
418 sub 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>
435 package Employee::Chef;
436 use Moose;
437
438 extends qw(Employee);
439
440 augment 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>
457 package Employee;
458 use Moose;
459 use Moose::Util::TypeConstraints;
460 extends qw(Person);
461
462 class_type 'Manager';
463
464 coerce 'Manager' => (
465     from 'Str' => via { Manager->new( name => $_ ) },
466 );
467
468 has 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
483 use Moose::Util::TypeConstraints;
484
485
486 # define Manager, a subtype of Object
487 class_type "Manager";
488
489
490 # define the conversion
491 ... via { Manager->new( name => $_ ) }
492
493
494 # enable it per attribute
495 has 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>
512 has employees => (
513     is => 'rw',
514     isa => 'ArrayRef[Employee]',
515 );
516
517 has 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>
534 has language => (
535     is => 'rw',
536     isa => 'English | Welsh | Scots | Gaelic',
537 );  
538
539 has 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>
554 package Foo;
555 use Moose;
556 use Moose::Util::TypeConstraints;
557
558 use Test::Deep qw(eq_deeply ...);
559
560 type 'SomethingTricky' => where {
561     eq_deeply( $_, ... );
562 };
563
564 has '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>
581 use Moose::Util::TypeConstraints;
582
583 subtype 'ArrayRef[Employee]' => as 'ArrayRef';
584
585 coerce 'ArrayRef[Employee]' => (
586     from 'ArrayRef[Str]' via {
587         [ map { Employee->new( name => $_ ) } @$_ ]
588     },
589 );
590
591 has 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>
644 package Minion;
645 use Moose;
646
647 extends qw(Employee);
648
649 with qw(Salaried::Hourly);
650
651
652 package Boss;
653 use Moose;
654
655 extends qw(Employee);
656
657 with 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>
674 package Salaried;
675 use Moose::Role;
676
677 requires '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>
690 package Salaried::Hourly;
691 use Moose::Role;
692
693 with qw(Salaried);
694
695 has hourly_rate => (
696     isa => "Num",
697     is  => "rw",
698     required => 1,
699 );
700
701 has logged_hours => (
702     isa => "Num",
703     is  => "rw",
704     default => 0,
705 );
706
707 # satisfy the Salaried interface:
708 sub 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
734 roles 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
766 multiple 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>
778 package Ballet;
779 use Moose::Role;
780
781 sub dance {
782     pirouette();
783 }
784
785 package Punk;
786 use Moose::Role
787
788 sub dance {
789     MOSH!!!11one();
790 }
791
792 package Foo;
793 use Moose;
794
795 # KABOOM:
796 with 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>
811 package Ent::Puppy;
812 use Moose;
813
814 with (
815     Tree => {
816         alias => {
817             bark => "tree_bark",
818         },
819     },
820     Dog => {
821         alias => {
822             bark => "bark_sound",
823         }
824     },
825 );
826
827 sub 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
844 Easier conflict resolution
845 Finer 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>
861 my $class = $obj->meta;       # $obj's metaclass
862 my $meta  = MyApp->meta;      # MyApp's metaclass
863 my $emo   = $obj->meta->meta; # even more meta!
864
865 warn  $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>
874 my $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>
896 Moose::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
909 my $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>
921 has 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>
946 has 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>
1161 package Units::Bytes;
1162 use Moose::Role;
1163 use Moose::Autobox;
1164
1165 sub bytes     { $_[0]                   }
1166 sub kilobytes { $_[0] * 1024            }
1167 sub megabytes { $_[0] * 1024->kilobytes }
1168 sub gigabytes { $_[0] * 1024->megabytes }
1169 sub terabytes { $_[0] * 1024->gigabytes }
1170
1171 Moose::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>
1182 use Units::Bytes;
1183 use Moose::Autobox; # autoboxing is lexical
1184
1185 is(5->bytes,     5,             '... got 5 bytes');
1186 is(5->kilobytes, 5120,          '... got 5 kilobytes');
1187 is(2->megabytes, 2097152,       '... got 2 megabytes');
1188 is(1->gigabytes, 1073741824,    '... got 1 gigabyte');
1189 is(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>
1202 perl -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>
1217 package Counter;
1218 use MooseX::POE;
1219 use MooseX::AttributeHelpers;
1220
1221 has count => (
1222     traits => [qw(Counter)],
1223     provides => { inc => "increment_count" },
1224 );
1225
1226 sub START {
1227     shift->yield('increment');
1228 }
1229
1230 event 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
1239 Counter->new( count => 0 );
1240 POE::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>