typo
[gitmo/moose-presentations.git] / moose-class / slides / index.html
index 2ddbdc1..a44f504 100644 (file)
@@ -52,7 +52,8 @@ img#me05 {top: 43px;left: 36px;}
 
 <div class="slide">
   <h1>Introduction to Moose</h1>
-  <h2>YAPC 2009</h2>
+  <h2>OSCON 2009</h2>
+  <h2><a href="git://git.moose.perl.org/moose-presentations.git"><tt>git://git.moose.perl.org/moose-presentations.git</tt></a></h2>
 </div>
 
 <div class="slide">
@@ -341,7 +342,7 @@ has blog_uri =&gt; (
   <h1>Why Moose?</h1>
 
   <ul>
-    <li>A quick bit of propoganda ...</li>
+    <li>A quick bit of propaganda ...</li>
   </ul>
 </div>
 
@@ -866,6 +867,98 @@ use Moose;</code></pre>
 </div>
 
 <div class="slide">
+  <h1>BUILDARGS</h1>
+
+  <ul>
+    <li>Takes <code>@_</code>, returns a hash reference of attribute names/value</li>
+    <li>Accepts a hash or hashref; throws otherwise</li>
+    <li>Provide your own for other cases</li>
+    <li><strong>Always</strong> call <code>$class-&gt;SUPER::BUILDARGS(@_)</code> as a fallback!</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>BUILDARGS Example</h1>
+
+  <pre><code>package Person;
+use Moose;
+
+sub BUILDARGS {
+    my $class = shift;
+
+    if ( @_ == 1 &amp;&amp; ! ref $_[0] ) {
+        <span class="highlight">return { ssn =&gt; $_[0] };</span>
+    }
+
+    <span class="highlight">return $class-&gt;SUPER::BUILDARGS(@_)</span>;
+}
+
+<span class="highlight">Person-&gt;new('123-45-6789')</span></code></pre>
+</div>
+
+<div class="slide">
+  <h1>BUILD</h1>
+
+  <ul>
+    <li>Called after object is created, before <code>new</code> returns</li>
+    <li>Chance to do more complex validation, set complex attributes</li>
+    <li>Called in reverse inheritance order, parents to children</li>
+    <li>Return value is ignored</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>BUILD Example</h1>
+
+  <pre><code>package Person;
+use Moose;
+
+sub BUILD {
+    my $self = shift;
+
+    if ( $self-&gt;country_of_residence
+         eq 'USA' ) {
+        die 'All US residents'
+            . ' must have an SSN'
+            unless $self-&gt;has_ssn;
+    }
+}</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Object Construction a la Moose</h1>
+
+  <pre><code>Person-&gt;new(@_)</code></pre>
+
+  <ol>
+    <li>Calls <code>Person-&gt;BUILDARGS(@_)</code> to turn <code>@_</code> into a hashref</li>
+    <li>Blesses a reference</li>
+    <li>Populates attributes based on the hashref from #1</li>
+    <li>Calls <code>$new_object->BUILDALL($constructor_args)</code>
+        <br />... which calls all <code>BUILD</code> methods</li>    
+    <li>Returns the object</li>
+  </ol>
+</div>
+
+<div class="slide">
+  <h1>The Object is Opaque</h1>
+
+  <ul>
+    <li>Technically it's a hash reference</li>
+    <li><span class="wrong">If you <em>ever</em> treat it as one <strong>you are doing it wrong!</strong></span></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>DEMOLISH</h1>
+
+  <ul>
+    <li>Like <code>DESTROY</code>, but Moose makes sure all <code>DEMOLISH</code> methods in a hierarchy are called</li>
+    <li>Called in normal inheritance order, children to parents</li>
+  </ul>
+</div>
+
+<div class="slide">
   <h1>extends</h1>
 
   <ul>
@@ -884,14 +977,14 @@ use Moose;
     <li>Each call to <code>extends</code> <strong>resets</strong> your parents</li>
   </ul>
 
-  <h2 class="wrong">WRONG</h2>
+  <h2 class="wrong">Wrong</h2>
 
   <pre><code>package EvilEmployee;
 use Moose;
 extends 'Person';
 extends 'Thief';</code></pre>
 
-  <h2 class="right">RIGHT</h2>
+  <h2 class="right">Right</h2>
 
   <pre><code>package EvilEmployee;
 use Moose;
@@ -918,23 +1011,23 @@ extends 'LWP';</code></pre>
 </div>  
 
 <div class="slide">
-  <h1><code>overrides</code> and <code>super</code></h1>
+  <h1><code>override</code> and <code>super</code></h1>
 
   <ul>
-    <li><code>overrides</code> is another method modifier</li>
+    <li><code>override</code> is another method modifier</li>
     <li>An alternative to Perl's <code>SUPER::</code></li>
   </ul>
 </div>
 
 <div class="slide">
-  <h1><code>overrides</code> and <code>super</code></h1>
+  <h1><code>override</code> and <code>super</code></h1>
 
   <pre><code>package Employee;
 use Moose;
 
 <span class="current incremental">extends 'Person';</span>
 
-<span class="incremental">overrides</span> work =&gt; sub {
+<span class="incremental">override</span> work =&gt; sub {
     my $self = shift;
 
     die "Pay me first" unless $self-&gt;got_paid;
@@ -953,7 +1046,7 @@ use Moose;
 </div>
 
 <div class="slide">
-  <h1>Attributes (Part 1)</h1>
+  <h1>Minimal Attributes</h1>
 
   <ul>
     <li><code>has 'foo'</code></li>
@@ -1035,6 +1128,7 @@ Person->can('extends');</code></pre>
 
   <ul>
     <li><code>no Moose</code> at the end of a package is a best practice</li>
+    <li>Or <code>namespace::clean</code> at the top</li>
     <li>Just do it</li>
   </ul>
 </div>
@@ -1080,7 +1174,7 @@ use Moose;
     <li><code>use Moose</code></li>
     <li><code>Class-&gt;meta</code></li>
     <li><code>Moose::Object</code> base class</li>
-    <li><code>extends</code>, <code>overrides</code>, and <code>super</code></li>
+    <li><code>extends</code>, <code>override</code>, and <code>super</code></li>
     <li>Simple attributes: <code>has</code>, <code>is&nbsp;=&gt;&nbsp;'ro'</code>, &amp; <code>is&nbsp;=&gt;&nbsp;'rw'</code></li>
     <li><code>no Moose</code></li>
     <li><code>__PACKAGE__-&gt;meta-&gt;make_immutable</code></li>
@@ -1095,9 +1189,10 @@ use Moose;
   <h1>Exercises</h1>
 
   <pre># cd exercises
-$ perl bin/prove -lv t/00-prereq.t
 
-Missing anything? Install it. (see tarballs/)
+# perl bin/prove -lv t/00-prereq.t
+
+# perl install-moose (if needed)
 
 # perl bin/prove -lv t/01-classes.t
 
@@ -1286,7 +1381,7 @@ use Moose;
   <h1>Conflict Resolution</h1>
 
   <ul>
-    <li>The consuming class must resolve the conflict by implementing th emethod</li>
+    <li>The consuming class must resolve the conflict by implementing the method</li>
     <li>Can use some combination of method exclusion and aliasing</li>
   </ul>
 </div>
@@ -1846,7 +1941,7 @@ sub _build_shoes {
     my $self = shift;
 
     return Shoes-&gt;new(
-        size =&gt; <span class="highlight">$_[0]-&gt;shoe_size</span> );
+        size =&gt; <span class="highlight">$self-&gt;shoe_size</span> );
 }</code></pre>
 </div>
 
@@ -1996,8 +2091,7 @@ has '<span class="highlight">+first_name</span>' =&gt; (
 use Moose;
 
 has first_name =&gt; (
-    <span class="highlight">reader</span> =&gt; 'first_name',
-    <span class="highlight">writer</span> =&gt; 'first_name',
+    <span class="highlight">accessor</span> =&gt; 'first_name',
 );</code></pre>
 
   <ul>
@@ -2030,7 +2124,7 @@ use Moose;
 
 has first_name =&gt; (
     <span class="highlight">reader</span> =&gt; 'get_first_name',
-    <span class="highlight">writer</span> =&gt; 'set_first_name,
+    <span class="highlight">writer</span> =&gt; 'set_first_name',
 );</code></pre>
 </div>
 
@@ -2046,7 +2140,7 @@ has first_name =&gt; (
 );</code></pre>
 
   <ul>
-    <li>Can also mix-and-match</li>
+    <li>Can also mix-and-match <code>is</code> and explicit names</li>
   </ul>
 </div>
 
@@ -2120,7 +2214,7 @@ Iterate til this passes all its tests</pre>
   <h1>What is a Method Modifier</h1>
 
   <ul>
-    <li>"Iinject" behavior</li>
+    <li>"Inject" behavior</li>
     <li>Add behavior to generated methods (accessors, delegations)</li>
     <li>Provide roles which modify existing behavior</li>
   </ul>
@@ -2330,12 +2424,14 @@ sub xml { '&lt;doc&gt;' . <span class="highlight">inner()</span> . '&lt;/doc&gt;
 package Report;
 extends 'Document';
 
-<span class="highlight">augment xml</span> =&gt; { title() . <span class="highlight">inner()</span> . summary() };
+<span class="highlight">augment xml</span> =&gt;
+    sub { title() . <span class="highlight">inner()</span> . summary() };
 
 package TPSReport;
 extends 'Report';
 
-<span class="highlight">augment xml</span> =&gt; { tps_xml() . <span class="highlight">inner()</span> };</code></pre>
+<span class="highlight">augment xml</span> =&gt;
+    sub { tps_xml() . <span class="highlight">inner()</span> };</code></pre>
 </div>
 
 <div class="slide">
@@ -2363,6 +2459,50 @@ extends 'Report';
 </div>
 
 <div class="slide">
+  <h1>Method Modifiers Summary</h1>
+
+  <ul>
+    <li>Use <code>before</code> and <code>after</code> for ...
+      <ul>
+        <li>logging</li>
+        <li>pre- or post-validation</li>
+        <li>to add behavior to generated methods</li>
+      </ul>
+    </li>
+    <li>These two modifiers cannot change parameters or return values</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Method Modifiers Summary</h1>
+
+  <ul>
+    <li>Use <code>around</code> to ...
+      <ul>
+        <li>alter parameters passed to the original method</li>
+        <li>alter the return value of the original method</li>
+        <li>not call the original method at all (or call a <em>different</em> method)</li>
+      </ul>
+    </li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Method Modifiers Summary</h1>
+
+  <ul>
+    <li>When using modifiers in a role, require the modified method</li>
+    <li>Use <code>augment</code> and <code>inner</code> to invert the normal subclassing flow ...
+      <ul>
+        <li>Least- to most-specific (parents to children)</li>
+        <li>Build in "insertability" (stick more stuff in the "middle")</li>
+      </ul>
+    </li>
+    <li>Always call <code>inner</code> in the most specific subclass to allow for future extension</li>
+  </ul>
+</div>
+
+<div class="slide">
   <h1>Questions?</h1>
 </div>  
 
@@ -2375,6 +2515,926 @@ extends 'Report';
 Iterate til this passes all its tests</pre>
 </div>
 
+<div class="slide fake-slide0">
+  <h1>Part 5: Types</h1>
+</div>
+
+<div class="slide">
+  <h1>A Type System for Perl</h1>
+
+  <ul>
+    <li>Sort of ...</li>
+    <li><em>Variables</em> are not typed</li>
+    <li>Attributes can have types</li>
+    <li>MooseX modules let you define method signatures</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Components of a Moose Type</h1>
+
+  <ul>
+    <li>A type is a name and a constraint</li>
+    <li>Types have a hierarchy</li>
+    <li>Constraints are cumulative from parents</li>
+    <li>Types can have associated coercions</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Built-in Type Hierarchy</h1>
+
+  <pre>
+Any
+Item
+    Bool
+    Maybe[`a]
+    Undef
+    Defined
+        Value
+           Num
+             Int
+           Str
+             ClassName
+             RoleName
+</pre>
+</div>
+
+<div class="slide">
+  <h1>Built-in Type Hierarchy</h1>
+
+<pre>
+(Item)
+    (Defined)
+        Ref
+            ScalarRef
+            ArrayRef[`a]
+            HashRef[`a]
+            CodeRef
+            RegexpRef
+            GlobRef
+              FileHandle
+            Object
+</pre>
+</div>
+
+<div class="slide">
+  <h1>Bool</h1>
+
+  <h2>True</h2>
+  <pre><code>1
+924.1
+'true'
+{}</code></pre>
+
+  <h2>False</h2>
+  <pre><code>0
+0.0
+'0'
+undef</code></pre>
+
+  <ul>
+    <li>Like Perl's <code>if ($foo)</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Value (and subtypes)</h1>
+
+  <ul>
+    <li><code>Value</code> is true when <code>! ref $thing</code></li>
+    <li><code>Value</code> and <code>Str</code> are effectively the same, but <code>Str</code> is more expressive</li>
+    <li>An overloaded object which numifies does not pass the <code>Num</code> constraint!</li>
+    <li>Perl 5's overloading is hopelessly broken</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>ClassName and RoleName</h1>
+
+  <ul>
+    <li>A string with a package name</li>
+    <li>The package <strong>must already be loaded</strong></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Parameterizable Types</h1>
+
+  <ul>
+    <li>What does <code>ArrayRef[`a]</code> mean?</li>
+    <li><code>s/`a/Int/</code> (or <code>Str</code> or ...)</li>
+    <li>When you use it you can write ...
+      <ul>
+        <li><code>ArrayRef</code> (== <code>ArrayRef[Item]</code>)</li>
+        <li><code>ArrayRef[Str]</code></li>
+        <li><code>ArrayRef[MyTypeName]</code></li>
+        <li><code>ArrayRef[HashRef[Maybe[Int]]]</code></li>
+      </ul>
+    </li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Maybe[`a]</h1>
+
+  <ul>
+    <li>Maybe means either the named type or <code>undef</code></li>
+    <li><code>Maybe[Int]</code> accepts integers or <code>undef</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Type Union</h1>
+
+  <ul>
+    <li>This or that (or that or ...)</li>
+    <li><code>Int | ArrayRef[Int]</code></li>
+    <li>But use a coercion instead when possible</li>
+    <li>Or use a <code>role_type</code>,  <code>duck_type</code>, or anything not a union</li>
+    <li>A union is often a code smell</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Making Your Own Types</h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+
+<span class="incremental current">subtype 'PositiveInt',</span>
+    <span class="incremental">as      'Int',</span>
+    <span class="incremental">where   { $_ &gt; 0 },</span>
+    <span class="incremental">message { "The value you provided ($_)"
+              . " was not a positive number." };</span>
+
+has size =&gt; (
+    is  =&gt; 'ro',
+    <span class="incremental">isa =&gt; 'PositiveInt',</span>
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Automatic Types</h1>
+
+  <ul>
+    <li>Moose creates a type for every Moose class and role</li>
+    <li>Unknown names are assumed to be classes</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Automatic Types</h1>
+
+  <pre><code>package Employee;
+use Moose;
+
+has manager =&gt; (
+    is  =&gt; 'rw',
+    <span class="highlight">isa =&gt; 'Employee',</span>
+);
+
+has start_date =&gt; (
+    is  =&gt; 'ro',
+    <span class="highlight">isa =&gt; 'DateTime',</span>
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Subtype Shortcuts - <code>class_type</code></h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+class_type 'DateTime';
+
+subtype 'DateTime',
+    as      'Object',
+    where   { $_-&gt;isa('DateTime') },
+    message { ... };</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Subtype Shortcuts - <code>role_type</code></h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+role_type 'Printable';
+
+subtype 'Printable',
+    as      'Object',
+    where
+        { Moose::Util::does_role(
+              $_, 'Printable' ) },
+    message { ... };</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Subtype Shortcuts - <code>duck_type</code></h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+duck_type Car =&gt; qw( run break_down );
+
+subtype 'Car',
+    as      'Object',
+    where   { all { $_-&gt;can($_) }
+              qw( run break_down ) },
+    message { ... };</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Subtype Shortcuts - <code>enum</code></h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+enum Color =&gt; qw( red blue green ) );
+
+my %ok = map { $_ =&gt; 1 } qw( red blue green );
+subtype 'Color'
+    as      'Str',
+    where   { $ok{$_} },
+    message { ... };</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Anonymous Subtypes</h1>
+
+  <pre><code>package Person;
+
+<span class="highlight">my $posint =
+    subtype as 'Int', where { $_ &gt; 0 };</span>
+
+has size =&gt; (
+    is  =&gt; 'ro',
+    <span class="highlight">isa =&gt; $posint,</span>
+);</code></pre>
+
+  <ul>
+    <li>Shortcuts have anonymous forms as well</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Coercions</h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+
+subtype 'UCStr',
+    as    'Str',
+    where { ! /[a-z]/ };
+
+<span class="incremental current">coerce 'UCStr',</span>
+    <span class="incremental">from 'Str',</span>
+    <span class="incremental">via  { uc };</span>
+
+has shouty_name =&gt; (
+    is     =&gt; 'ro',
+    isa    =&gt; 'UCStr',
+    <span class="incremental">coerce =&gt; 1,</span>
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Coercion Examples</h1>
+
+  <pre><code>subtype 'My::DateTime',
+    as class_type 'DateTime';
+
+coerce 'My::DateTime',
+    from 'HashRef',
+    via  { DateTime-&gt;new( %{$_} ) };
+
+coerce 'My::DateTime',
+    from 'Int',
+    via  { DateTime-&gt;from_epoch(
+               epoch =&gt; $_ ) };</code></pre>
+
+  <ul>
+    <li>Use coercion to inflate a value</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Coercion Examples</h1>
+
+  <pre><code>coerce 'ArrayRef[Int]',
+    from 'Int',
+    via  { [ $_ ] };</code></pre>
+
+  <ul>
+    <li>Coerce instead of a union like <code style="white-space: nowrap">Int | ArrayRef[Int]</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Using Types with Attributes</h1>
+
+  <pre><code>package Person;
+
+use Moose::Util::TypeConstraints;
+
+has height =&gt; (
+    is  =&gt; 'rw',
+    <span class="highlight">isa =&gt; 'Num',</span>
+);
+
+has favorite_numbers =&gt; (
+    is     =&gt; 'rw',
+    <span class="highlight">isa    =&gt; 'ArrayRef[Int]',
+    coerce =&gt; 1,</span>
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>More Droppings</h1>
+
+  <ul>
+    <li><code>Moose::Util::TypeConstraint</code> also needs cleanup</li>
+  </ul>
+
+  <pre><code>package Person;
+
+use Moose;
+use Moose::Util::TypeConstraints;
+
+subtype ...;
+
+no Moose;
+<span class="highlight">no Moose::Util::TypeConstraints;</span></code></pre>
+</div>
+
+<div class="slide">
+  <h1>Typed Methods (Low-tech)</h1>
+
+  <pre class="medium"><code>package Person;
+<span class="highlight">use MooseX::Params::Validate qw( validated_list );</span>
+
+sub work {
+    my $self = shift;
+    <span class="highlight">my ( $tasks, $can_rest ) =
+        validated_list(
+            \@_,
+            tasks    =&gt;
+                { isa    =&gt; 'ArrayRef[Task]',
+                  coerce =&gt;1 },
+            can_rest =&gt;
+                { isa     =&gt; 'Bool',
+                  default =&gt; 0 },
+        );</span>
+
+    ...
+}</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Typed Methods (High-tech)</h1>
+
+  <pre class="medium"><code>package Person;
+
+<span class="highlight">use MooseX::Method::Signatures;</span>
+
+<span class="highlight">method work ( ArrayRef[Task] :$tasks,
+                        Bool :$can_rest = 0 )</span> {
+    my $self = shift;
+
+    ...
+}</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Digression: The Type Registry</h1>
+
+  <ul>
+    <li>Types are actually <code>Moose::Meta::TypeConstraint</code> <em>objects</em></li>
+    <li>Stored in an interpreter-global registry mapping names to objects</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Danger!</h1>
+
+  <ul>
+    <li>Coercions are attached to type objects</li>
+    <li>Therefore also global</li>
+    <li>Name conflicts between modules!</li>
+    <li>Coercion conflicts between modules!</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Namespace Fix</h1>
+
+  <ul>
+    <li>Use some sort of pseudo-namespacing scheme</li>
+    <li>Never coerce directly to a class name, or <em>to</em> built-in types</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Namespace Fix</h1>
+
+  <pre><code>use Moose::Util::TypeConstraints;
+
+subtype <span class="highlight">'MyApp::Type::DateTime',</span>
+    as 'DateTime';
+
+<span class="highlight">coerce 'MyApp::Type::DateTime',</span>
+    from 'HashRef',
+    via  { DateTime-&gt;new( %{$_} ) }
+
+has creation_date =&gt; (
+    is     =&gt; 'ro',
+    <span class="highlight">isa    =&gt; 'MyApp::Type::DateTime',</span>
+    coerce =&gt; 1,
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Namespace Fix</h1>
+
+  <pre><code>subtype 'MyApp::Type::ArrayOfInt',
+    as 'ArrayRef[Int]';
+
+coerce 'MyApp::Type::ArrayOfInt',
+    from 'Int',
+    via  { [ $_ ] };</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Namespace Fix Pros and Cons</h1>
+
+  <ul>
+    <li><span class="right">Relatively simple</span></li>
+    <li><span class="right">Already built into Moose</span></li>
+    <li><span class="wrong">Conflates type and module namespaces</span></li>
+    <li><span class="wrong">Type names are strings, so typos are easy to make and may be hard to find</span></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>MooseX::Types</h1>
+
+  <pre><code>package MyApp::Types;
+
+use MooseX::Types
+    <span class="highlight">-declare =&gt; [ qw( ArrayOfInt ) ]</span>;
+use MooseX::Types::Moose
+    qw( ArrayRef Int );
+
+subtype <span class="highlight">ArrayOfInt</span>,
+    as ArrayRef[Int];
+
+coerce <span class="highlight">ArrayOfInt</span>
+    from Int,
+    via  { [ $_ ] };</code></pre>
+</div>
+
+<div class="slide">
+  <h1>MooseX::Types</h1>
+
+  <pre><code>package MyApp::Account;
+
+use MyApp::Types qw( ArrayOfInt );
+
+has transaction_history => (
+    is  => 'rw',
+    isa => ArrayOfInt,
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>MooseX::Types</h1>
+
+  <ul>
+    <li>Type names are exported functions, catches typos early</li>
+    <li>Types must be pre-declared</li>
+    <li>Types are stored with namespaces internally, but externally are short</li>
+    <li>Import existing Moose types as functions from <code>MooseX::Types::Moose</code></li>
+    <li>Still need string names for things like <code>ArrayRef['Email::Address']</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>MooseX::Types Pros and Cons</h1>
+
+  <ul>
+    <li><span class="right">Catches typos at compile time</span></li>
+    <li><span class="right">Automatic namespacing</span></li>
+    <li><span class="wrong">One more thing to install and learn</span></li>
+    <li><span class="wrong">Every name gets types twice (declared and then defined)</span></li>
+    <li><span class="wrong">Still stuck with strings when referring to class or role names</span></li>
+    <li><span class="wrong">Coercion gotcha from earlier still applies to types exported from <code>MooseX::Types::Moose</code></span></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Recommendation</h1>
+
+  <ul>
+    <li>Use <code>MooseX::Types</code></li>
+    <li>Compile time error catching and automatic namespacing are huge wins</li>
+    <li>Docs from <code>Moose::Util::TypeConstraints</code> are 98% compatible with <code>MooseX::Types</code> anyway</li>
+    <li>A function exported by a type library works wherever a type name would</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Questions?</h1>
+</div>  
+
+<div class="slide">
+  <h1>Exercises</h1>
+
+  <pre># cd exercises
+# perl bin/prove -lv t/05-types.t
+
+Iterate til this passes all its tests</pre>
+</div>
+
+<div class="slide fake-slide0">
+  <h1>Part 6: Advanced Attributes</h1>
+</div>
+
+<div class="slide">
+  <h1>Weak References</h1>
+
+  <ul>
+    <li>A weak reference lets you avoid circular references</li>
+    <li>Weak references do not increase the reference count</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Circular Reference Illustrated</h1>
+
+  <pre><code>my $foo = {};
+my $bar = { foo =&gt; $foo };
+$foo-&gt;{bar} = $bar;</code></pre>
+
+  <ul>
+    <li>Neither <code>$foo</code> nor <code>$bar</code> go out of scope<br />
+        (until the program exits)</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Weakening Circular References</h1>
+
+  <pre><code>use Scalar::Util qw( weaken );
+
+my $foo = {};
+my $bar = { foo =&gt; $foo };
+$foo-&gt;{bar} = $bar;
+weaken $foo-&gt;{bar}</code></pre>
+
+  <ul>
+    <li>When <code>$bar</code> goes out of scope, <code>$foo-&gt;{bar}</code> becomes <code>undef</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Circular References in Attributes</h1>
+
+  <pre><code>package Person;
+use Moose;
+
+has name   =&gt; ( is =&gt; 'ro' );
+has friend =&gt; ( is =&gt; 'rw' );
+
+my $alice = Person-&gt;new( name =&gt; 'Alice' );
+my $bob   = Person-&gt;new( name =&gt; 'Bob' );
+$bob-&gt;friend($alice);
+$alice-&gt;friend($bob);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>The Fix</h1>
+
+  <pre><code>package Person;
+use Moose;
+
+has name   =&gt; ( is =&gt; 'ro' );
+has friend =&gt; ( is =&gt; 'rw', <span class="highlight">weak_ref =&gt; 1</span> );
+
+my $alice = Person-&gt;new( name =&gt; 'Alice' );
+my $bob   = Person-&gt;new( name =&gt; 'Bob' );
+$bob-&gt;friend($alice);
+$alice-&gt;friend($bob);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Under the Hood</h1>
+
+  <ul>
+    <li>A <code>weak_ref</code> attribute calls <code>weaken</code> ...
+      <ul>
+        <li>during object construction</li>
+        <li>when the attribute is set via a writer</li>
+      </ul>
+    </li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Triggers</h1>
+
+  <ul>
+    <li>A code reference run after an attribute is <em>set</em></li>
+    <li>Like an <code>after</code> modifier, but makes intentions clearer</li>
+  </ul>
+
+  <h2 class="wrong">Gross</h2>
+
+  <pre><code>after salary_level =&gt; {
+    my $self = shift;
+    return unless @_;
+    $self-&gt;clear_salary;
+};</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Use a Trigger Instead</h1>
+
+  <h2 class="right">Cleaner</h2>
+
+  <pre><code>has salary_level =&gt; (
+    is      =&gt; 'rw',
+    trigger =&gt; sub { $_[0]-&gt;clear_salary },
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Delegation</h1>
+
+  <ul>
+    <li>Attributes can be objects</li>
+    <li>Delegation transparently calls methods on those objects</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Delegation Examples</h1>
+
+  <pre><code>package Person;
+
+has lungs =&gt; (
+    is      =&gt; 'ro',
+    isa     => 'Lungs',
+    <span class="highlight">handles =&gt; [ 'inhale', 'exhale' ],</span>
+);</code></pre>
+
+  <ul>
+    <li>Creates <code>$person-&gt;inhale</code> and <code>-&gt;exhale</code> methods</li>
+    <li>Internally calls <code>$person-&gt;lungs-&gt;inhale</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Why Delegation?</h1>
+
+  <ul>
+    <li>Reduce the number of classes exposed</li>
+    <li>Re-arrange class internals -<br />
+        turn a method into an attribute with delegation</li>
+    <li>Provide convenenience methods</li>
+  </ul>
+</div> 
+
+<div class="slide">
+  <h1>Moose's <code>handles</code> Parameter</h1>
+
+  <ul>
+    <li>Accepts many arguments ...
+      <ul>
+        <li>Array reference - list of methods to delegate as-is</li>
+        <li>Hash reference - map of method names</li>
+        <li>Regex - delegates all matching methods</li>
+        <li>Role name - delegates all methods in the role</li>
+        <li>Sub reference - does something complicated ;)</li>
+      </ul>
+    </li>
+  </ul>
+</div>      
+
+<div class="slide">
+  <h1>Array Reference</h1>
+
+  <ul>
+    <li>Takes each method name and creates a simple delegation from the delegating class to the delegatee attribute</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Hash Reference</h1>
+
+  <ul>
+    <li>Mapping of names in the delegating class to the delegatee class</li>
+  </ul>
+
+  <pre><code>package Person;
+use Moose;
+
+has account =&gt; (
+    is      =&gt; 'ro',
+    isa     =&gt; 'BankAccount',
+    <span class="highlight">handles =&gt; {
+        receive_money =&gt; 'deposit',
+        give_money    =&gt; 'withdraw',
+    },</span>
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Hash Reference Detailed</h1>
+
+  <pre><code>    handles =&gt; {
+        receive_money =&gt; 'deposit',
+        give_money    =&gt; 'withdraw',
+    },</code></pre>
+
+  <ul>
+    <li><code>$person-&gt;receive_money</code> = <code>$person-&gt;account-&gt;deposit</code></li>
+    <li><code>$person-&gt;give_money</code> = <code>$person-&gt;account-&gt;withdraw</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Regex</h1>
+
+  <pre><code>package Person;
+use Moose;
+
+has name =&gt; (
+    is      =&gt; 'ro',
+    isa     =&gt; 'Name',
+    handles =&gt; qr/.*/,
+);</code></pre>
+
+  <ul>
+    <li>Creates a delegation for every method in the Name class</li>
+    <li>Excludes <code>meta</code> and methods inherited from <code>Moose::Object</code></li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Role Name</h1>
+
+  <pre><code>package Auditor;
+use Moose::Role;
+
+sub record_change  { ... }
+sub change_history { ... }
+
+package Account;
+use Moose;
+
+has history =&gt; (
+    is      =&gt; 'ro',
+    does    =&gt; 'Auditor',
+    <span class="highlight">handles =&gt; 'Auditor',</span>
+);</code></pre>
+</div>
+
+<div class="slide">
+  <h1>Role Name Detailed</h1>
+
+  <ul>
+    <li>Account gets delegate methods for each method in the <code>Auditor</code> role
+      <ul>
+        <li>record_history</li>
+        <li>change_history</li>
+      </ul>
+    </li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Traits and Metaclasses</h1>
+
+  <ul>
+    <li>The ultimate in customization</li>
+    <li>Per attribute metaclasses</li>
+    <li>Per attribute roles applied to the attribute metaclass</li>
+    <li>Change the meta-level behavior</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Traits and Metaclasses</h1>
+
+  <ul>
+    <li>The default metaclass is <code>Moose::Meta::Attribute</code></li>
+    <li>Controls accessor generation, defaults, delegation, etc.</li>
+    <li>Adding a role to this metaclass (or replacing it) allows for infinite customization</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Traits and Metaclasses</h1>
+
+  <ul>
+    <li>Can add/alter/remove attribute parameter (from <code>has</code>)</li>
+    <li>Can change behavior of created attribute</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Simple Trait Example</h1>
+
+  <pre><code>package Person;
+use Moose;
+use MooseX::LabeledAttributes;
+
+has ssn =&gt; (
+    <span class="highlight">traits =&gt; [ 'Labeled' ],</span>
+    is     =&gt; 'ro',
+    isa    =&gt; 'Str',
+    <span class="highlight">label  =&gt; 'Social Security Number',</span>
+);
+
+print <span class="highlight">Person-&gt;meta
+            -&gt;get_attribute('ssn')-&gt;label;</span></code></pre>
+</div>
+
+<div class="slide">
+  <h1>Simple Metaclass Example</h1>
+
+  <pre><code>package Person;
+use Moose;
+use MooseX::LabeledAttributes;
+
+has ssn =&gt; (
+    <span class="highlight">metaclass =&gt;
+        'MooseX::Meta::Attribute::Labeled',</span>
+    is        =&gt; 'ro',
+    isa       =&gt; 'Str',
+    <span class="highlight">label     =&gt; 'Social Security Number',</span>
+);
+
+print <span class="highlight">Person-&gt;meta
+            -&gt;get_attribute('ssn')-&gt;label;</span></code></pre>
+</div>
+
+<div class="slide">
+  <h1>Traits vs Metaclass</h1>
+
+  <ul>
+    <li>Can apply any mix of traits to an attribute</li>
+    <li>But just one metaclass</li>
+    <li>Traits (aka roles) can cooperate</li>
+    <li>Metaclasses require you to pick just one</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Advanced Attributes Summary</h1>
+
+  <ul>
+    <li>Use <code>weak_ref</code> to avoid circular references</li>
+    <li>Use trigger to do an action post-attribute write</li>
+    <li>Use delegations to hide "internal" objects</li>
+    <li>Traits and metaclasses let you extend Moose's core attribute features</li>
+  </ul>
+</div>
+
+<div class="slide">
+  <h1>Questions?</h1>
+</div>  
+
+<div class="slide">
+  <h1>Exercises</h1>
+
+  <pre># cd exercises
+# perl bin/prove -lv t/06-advanced-attributes.t
+
+Iterate til this passes all its tests</pre>
+</div>
+
+<div class="slide fake-slide0">
+  <h1>Part 7: Introspection</h1>
+</div>
+
+<div class="slide fake-slide0">
+  <h1>Part 8: A Tour of MooseX</h1>
+</div>
+
+<div class="slide fake-slide0">
+  <h1>Part 9: Writing Moose Extensions</h1>
+</div>
+
+<div class="slide fake-slide0">
+  <h1>The End</h1>
+</div>
+
+<div class="slide">
+  <h1>More Information</h1>
+
+  <ul>
+    <li><a href="http://moose.perl.org/">http://moose.perl.org/</a></li>
+    <li><a href="http://search.cpan.org/dist/Moose/lib/Moose/Manual.pod">Moose::Manual</a> and <a href="http://search.cpan.org/dist/Moose/lib/Moose/Cookbook.pod">Moose::Cookbook</a></li>
+    <li><a href="irc://irc.perl.org/#moose">irc://irc.perl.org/#moose</a></li>
+    <li>mailing list - <a href="mailto:moose@perl.org">moose@perl.org</a></li>
+    <li>Slides and exercises are in Moose's git repo:
+        <br />
+        <span style="white-space: nowrap">git://jules.scsys.co.uk/gitmo/moose-presentations</span></li>
+  </ul>
+</div>
+
 </div> 
 </body>
 </html>