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