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