Merge branch 'topic/2009-conferences' of gitmo@git.moose.perl.org:moose-website
[gitmo/moose-website.git] / hosted-presentations / 2008 / nothingmuch-YAPC-Asia / practical_moose.html
CommitLineData
720accfe 1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml">
6
7<head>
8<title>Moose</title>
9<!-- metadata -->
10<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
11<meta name="generator" content="TextMate/S5" />
12<meta name="version" content="S5 1.2a2" />
13<meta name="presdate" content="2008" />
14<meta name="author" content="Yuval Kogman" />
15<meta name="company" content="" />
16<!-- configuration parameters -->
17<meta name="defaultView" content="slideshow" />
18<meta name="controlVis" content="visible" />
19<!-- style sheet links -->
20<link rel="stylesheet" href="./ui/moose/slides.css" type="text/css" media="projection" id="slideProj" />
21<link rel="stylesheet" href="./ui/moose/outline.css" type="text/css" media="screen" id="outlineStyle" />
22<link rel="stylesheet" href="./ui/moose/print.css" type="text/css" media="print" id="slidePrint" />
23<link rel="stylesheet" href="./ui/moose/opera.css" type="text/css" media="projection" id="operaFix" />
24<!-- embedded styles -->
25<style type="text/css" media="all">
26.imgcon {width: 525px; margin: 0 auto; padding: 0; text-align: center;}
27#anim {width: 270px; height: 320px; position: relative; margin-top: 0.5em;}
28#anim img {position: absolute; top: 42px; left: 24px;}
29img#me01 {top: 0; left: 0;}
30img#me02 {left: 23px;}
31img#me04 {top: 44px;}
32img#me05 {top: 43px;left: 36px;}
33</style>
34<!-- S5 JS -->
35<script src="./ui/moose/slides.js" type="text/javascript"></script>
36</head>
37<body>
38
39<div class="layout">
40<div id="controls"><!-- DO NOT EDIT --></div>
41<div id="currentSlide"><!-- DO NOT EDIT --></div>
42<div id="header"></div>
43<div id="footer">
44<h1>YAPC::Asia::2008</h1>
45<h2>Moose</h2>
46</div>
47<div class="topleft"></div>
48<div class="topright"></div>
49<div class="bottomleft"></div>
50<div class="bottomright"></div>
51</div>
52
53<div class="presentation">
54
55<div class="slide">
56<h1>Moose</h1>
57<h2></h2>
58<h3>Yuval Kogman</h3>
59<h4></h4>
60</div>
61
62
63<div class="slide">
64<h1>Moose はなにではないか</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>
117package Person;
118
119use strict;
120use warnings;
121
122sub new {
123 my ($class) = @_;
124
125 return bless {
126 name => '',
127 age => undef,
128 }, $class;
129}
130
131sub name {
132 my ($self, $name) = @_;
133 $self->{'name'} = $name if $name;
134 return $self->{'name'};
135}
136
137sub age {
138 my ($self, $age) = @_;
139 $self->{'age'} = $age if $age;
140 return $self->{'age'};
141}
142
1431;
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>
154package Person;
155use Moose;
156
157has name => (is => 'rw');
158has age => (is => 'rw');
159
1601;
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>今度はアトリビュートの機能を説明していくよ
200Now 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>
210package Person;
211use Moose;
212
213has name => (
214 is => 'rw',
215 isa => 'Str'
216 default => 'Bob'
217);
218
219has 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 が追加されてます
229Adds 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>デフォルトの話
256discusses default</p>
257
258<p>リファレンスでないと想定外の共有がむずかしくなる
259non 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, 型の制約
285isa, 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>型の階層構造
313type 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>
323package Employee;
324use Moose;
325use Moose::Util::TypeConstraints;
326extends qw(Person);
327
328class_type 'Manager';
329
330coerce 'Manager'
331 => from 'Str'
332 => via { Manager->new( name => $_) };
333
334has 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)
351use Moose::Util::TypeConstraints;
352
353
354# オブジェクトのサブタイプであるマネージャーを定義(define Manager, a subtype of Object)
355class_type "Manager";
356
357
358# 変換を定義する(define the conversion)
359coerce 'Manager'
360 => from 'Str'
361 => via { Manager->new( name => $_) };
362
363
364# アトリビュートごとに有効にする(enable it per attribute)
365has manager => (
366
367 coerce => 1,
368);
369</code></pre>
370
371<div class="notes">
372<p>例を細かく見ていくよ
373breakdown of the example</p>
374
375<p>クラスの型はMooseのクラスすべてに自動的に用意されます
376class 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>
386package Employee;
387use Moose;
388extends qw(Person);
389
390has 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>
416has 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>
430has 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>
449has 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>
463package Company;
464use Moose;
465use MooseX::AttributeHelpers;
466
467has 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>
488before 'employees' => sub { warn 'calling employees' };
489
490after '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>
510around '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>
527package Employee;
528use Moose;
529
530sub 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>
549package Employee::Chef;
550use Moose;
551
552extends qw(Employee);
553
554augment 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>
573has employees => (
574 is => 'rw',
575 isa => 'ArrayRef[Employee]',
576);
577
578has shopping_carts => (
579 is => 'rw',
580 isa => 'ArrayRef[ArrayRef[ShinyBead]]'
581);
582</code></pre>
583
584<div class="notes">
585<p>型システムの機能についてちょっと説明していくよ
586Going to go into features of the type system for a bit</p>
587
588<p>パラメータ付きの型
589Parametrized 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>
599has language => (
600 is => 'rw',
601 isa => 'English | Welsh | Scots | Gaelic',
602);
603
604has member => (
605 is => 'rw',
606 isa => 'Employee | ArrayRef[Employee|Group]',
607);
608</code></pre>
609
610<div class="notes">
611<p>型の結合
612Union 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>
622package Foo;
623use Moose;
624use Moose::Util::TypeConstraints;
625use Test::Deep qw(eq_deeply ...);
626
627type 'SomethingTricky'
628 => where {
629 eq_deeply( $_, ... );
630 };
631
632has 'bar' => (
633 is => 'rw',
634 isa => 'SomethingTricky',
635);
636</code></pre>
637
638<div class="notes">
639<p>Test::Deppのカスタムバリデータ
640Test::Deep custom validator</p>
641
642<p>CPANからどんなバリデータでも持ってこられる
643Can 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>
653use Moose::Util::TypeConstraints;
654subtype 'ArrayRef[Employee]' => as 'ArrayRef';
655
656coerce 'ArrayRef[Employee]'
657 => from 'ArrayRef[Str]'
658 => via { [ map { Employee->new( name => $_ ) } @$_ ] };
659
660has 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] に強制変換
671coerce parametrized ArrayRef[Employee] from ArrayRef[Str]</p>
672
673<p>強制変換は &#8216;default&#8217; の返り値にも適用されます
674coercions 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>再利用可能な小さな動作の例
716Some examples of small reusable behaviors</p>
717
718<p>Paramは連携に便利
719Param 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>
729package Minion;
730use Moose;
731
732extends qw(Employee);
733
734with qw(Salaried::Hourly);
735
736package Boss;
737use Moose;
738
739extends qw(Employee);
740
741with 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>
762package Salaried;
763use Moose::Role;
764
765requires 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>
781package Salaried::Hourly;
782use Moose::Role;
783
784with qw(Salaried);
785
786has hourly_rate => (
787 isa => "Num",
788 is => "rw",
789 required => 1,
790);
791
792has logged_hours => (
793 isa => "Num",
794 is => "rw",
795 default => 0,
796);
797
798sub 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はアトリビュートとメソッドを持てる
831roles can have attributes and methods
832Roleはインターフェースだけでなく動作を提供するもの
833roles 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が同じものを定義しようとした場合はコンパイル時にエラーになる(直さないといけない)
869symmetric 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多重継承の場合はだまって最初のクラスを使うもんだと想定してしまう
871multiple inheritence silently assumes you want the first class</p>
872
873<p>Roleは多重継承と違ってコンパイル時にエラーを吐く
874roles cause errors at compile time, unlike multiple inheritence</p>
875
876<p>Roleは簡単にエラーを修正する方法も用意している
877roles 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>
887package First;
888use Moose::Role;
889
890sub dancing { ... }
891
892package Second;
893use Moose::Role
894
895sub dancing { ... }
896
897package Foo;
898use Moose;
899
900# KABOOM
901with qw(
902 First
903 Second
904);
905</code></pre>
906
907<div class="notes">
908<p>衝突
909conflicts</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>
919package Ent::Puppy;
920use Moose;
921
922with (
923 Tree => {
924 alias => {
925 bark => "tree_bark",
926 },
927 },
928 Dog => {
929 alias => {
930 bark => "bark_sound",
931 }
932 },
933);
934
935sub 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>組み込むときにパラメータをつける
948Composition parameters
949衝突を解決するのも簡単だし
950Easier conflict resolution
951よりきめ細かいコントロールができるようになる
952Finer 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>
971my $class = $obj->meta; # $objのメタクラス($obj's metaclass)
972my $meta = MyApp->meta; # MyAppのメタクラス(MyApp's metaclass)
973my $emo = $obj->meta->meta # メタメタ(even more meta)!
974
975warn $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>
986my $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>
1012Moose::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>クラスはプログラム的につくることもできる
1028Classes can be created programmatically</p>
1029
1030<p>無名クラスも可
1031Anonymous 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>
1041has 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>
1066has 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>
1331package Units::Bytes;
1332use Moose::Role;
1333use Moose::Autobox;
1334
1335sub bytes { $_[0] }
1336sub kilobytes { $_[0] * 1024 }
1337sub megabytes { $_[0] * 1024->kilobytes }
1338sub gigabytes { $_[0] * 1024->megabytes }
1339sub terabytes { $_[0] * 1024->gigabytes }
1340
1341Moose::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>
1352use Units::Bytes;
1353use Moose::Autobox;
1354
1355is(5->bytes, 5, '... got 5 bytes');
1356is(5->kilobytes, 5120, '... got 5 kilobytes');
1357is(2->megabytes, 2097152, '... got 2 megabytes');
1358is(1->gigabytes, 1073741824, '... got 1 gigabyte');
1359is(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>
1373perl -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>
1389package Counter;
1390use MooseX::POE;
1391
1392has count => (
1393 isa => 'Int',
1394 is => 'rw',
1395);
1396
1397sub START {
1398 my ($self) = @_;
1399 $self->yield('increment');
1400}
1401
1402event 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
1409Counter->new( count => 0 );
1410POE::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>