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