Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

395 lines (351 sloc) 12.829 kb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Van.pm - Intro to Moose</title>
<!-- metadata -->
<meta name="generator" content="S5" />
<meta name="version" content="S5 1.1" />
<meta name="presdate" content="20091014" />
<meta name="author" content="Jeremy Stashewsky" />
<meta name="company" content="Socialtext" />
<!-- configuration parameters -->
<meta name="defaultView" content="slideshow" />
<meta name="controlVis" content="hidden" />
<!-- style sheet links -->
<link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
<link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
<link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
<link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
<!-- S5 JS -->
<script src="ui/default/slides.js" type="text/javascript"></script>
</head>
<body>
<div class="layout">
<div id="controls"><!-- DO NOT EDIT --></div>
<div id="currentSlide"><!-- DO NOT EDIT --></div>
<div id="header"></div>
<div id="footer">
<h1>Van.pm - Oct 14th 2009</h1>
<h2>Intro to Moose</h2>
</div>
</div>
<div class="presentation">
<div class="slide">
<h1>Intro to Moose</h1>
<h2></h2>
<h3>Jeremy Stashewsky</h3>
<h4>Socialtext Inc. <img src="logo.png" /></h4>
</div>
<div class="slide">
<h1>Overview</h1>
<ul>
<li>What is Moose?</li>
<li>Attributes</li>
<li>Constructors</li>
<li>Type Constraints</li>
<li>Roles</li>
<li>Method wrappers</li>
<li>Further reading</li>
</ul>
</div>
<div class="slide">
<h1>What is Moose?</h1>
</div>
<div class="slide">
<h1>Moose is...</h1>
<ul>
<li><strike>the largest extant species in the deer family</strike></li>
<li>a postmodern object system</li>
<li>an extension of the Perl 5 object system</li>
<li>a movement in the Perl community</li>
<li>build around ideas from Perl 6's meta-object protocol</li>
</ul>
</div>
<div class="slide">
<h1>Moose is more specifically...</h1>
<ul>
<li>a way to build your classes that doesn't suck</li>
<li>available for Perl 5.8 and up</li>
</ul>
</div>
<div class="slide">
<h1>Let's Dive In</h1>
<pre>
package Point;
use Moose;
has 'x' => (
is => 'rw', isa => 'Int',
default => 0,
);
has 'y' => (
is => 'rw', isa => 'Int',
default => 0,
);
</pre>
</div>
<div class="slide">
<h1>Old and Busted, New Hotness</h1>
<pre style="font-size: 60%">
package PointClassic; # 34 lines package Point; # 4 to 12 lines
use warnings; use Moose;
use strict;
has 'x' => (
my $int_pat = qr/^-?[0-9]+$/; is => 'rw', isa => 'Int',
default => 0,
sub new { );
my $class = shift;
my %p = @_==1 ? %{$_[0]} : @_; has 'y' => (
my $self = bless {}, $class; is => 'rw', isa => 'Int',
$self->x($p{x} || 0); default => 0,
$self->y($p{y} || 0); );
return $self;
}
sub x {
my $self = shift;
if (@_) {
my $x = shift;
die "x isn't an int" if $x !~ $int_pat;
$self->{x} = $x;
}
return $self->{x};
}
# ^^^^ repeat for y
</pre>
</div>
<div class="slide">
<h1>First example summary</h1>
<ul>
<li>Moose makes the <code>new()</code> constructor for us</li>
<li>The constructor accepts key-value pairs for parameters (or a hash-ref)</li>
<li>Sets up getter-setter methods for each attribute <em>named</em> after that attribute</li>
<li>Type-checks each attribute</li>
<li>Gives us a <code>dump</code> method for easy debugging</li>
</ul>
</div>
<div class="slide">
<h1>Attributes</h1>
<ul>
<li>Defined using <code>has 'name' =&gt; (... params ...)</code></li>
<li><code>is</code> defines if it's read-write "rw" or read-only "ro"</li>
<li><code>isa</code> defines the type of attribute (e.g. Int, Str, ArrayRef, HashRef)</li>
<li><code>default</code> specifies the default value if not passed in to the constructor, can be a code ref like <code>sub { 42 }</code> or <code>sub { [] }</code></li>
<li><code>required</code> makes this attribute required in the constructor, can never be undef</li>
</ul>
</div>
<div class="slide">
<h1>More Attribute Properties</h1>
<ul>
<li><code>getter</code> defines the name of the reading method</li>
<li><code>setter</code> defines the name of the writing method (hint: use "_$name" to make an "rw" attr. private)</li>
<li><code>clearer</code> defines the name of a method to clear (delete) this attribute</li>
<li><code>predicate</code> defines the name of a method to check if this attribute is defined</li>
<li><code>init_param</code> specify a replacement name for this attribute in the constructor (hint: use undef to prevent assignment during construction)</li>
<li><code>trigger</code> run this code ref after this attribute changes</li>
</ul>
</div>
<div class="slide">
<h1>Lazy Attributes</h1>
<ul>
<li><code>lazy =&gt; 1</code> specifies that the default doesn't take effect until read via an accessor.</li>
<li><code>builder</code> the name of a method to call to "build up" the default value</li>
<ul>
<li>not just for lazy attributes</li>
<li>builder is preferable to using default for complex initialization and if using inheritance or Roles</li>
</ul>
<li><code>lazy_build</code> turns on <code>lazy</code>, sets <code>builder</code> to "_build_foo", <code>clearer</code> to "clear_foo" and <code>predicate</code> to "has_foo"</li>
</ul>
</div>
<div class="slide">
<h1>Reference Attributes</h1>
<ul>
<li><code>Ref, ArrayRef, HashRef, ScalarRef</code> and <code>Object</code> types</li>
<li>if <code>isa</code> is given a class name, it will automatically make that an Object sub-type</li>
<li><code>weak_ref</code> weaken references passed in to the setter and constructor to allow garbage collection of circular refs</li>
<li><code>auto_deref</code> for ArrayRef and HashRef only: automatically dereference the getter</li>
<li><code>handles</code> for Object and specific sub-types only: delegate methods in this class to methods on the contained object</li>
</ul>
</div>
<div class="slide">
<h1>Example 2</h1>
<ul><li>example2.pl</li>
</ul>
</div>
<div class="slide">
<h1>Construction and Destruction</h1>
<ul>
<li>make a method called <code>BUILDARGS</code> to modify constructor parameters</li>
<ul>
<li>passed in raw paremeters, returns parameters to use instead</li>
<li>useful for making positional param. constructors or to mix positional and key-value</li>
</ul>
<li>make a method called <code>BUILD</code> and it will get called after construction</li>
<ul>
<li>passed $self and $params hashref.</li>
</ul>
<li>make a method called <code>DEMOLISH</code> and it will get called when an object is destroyed</li>
<li>All of the above cannot be "overridden" with inheritance; every BUILD method in the hierarchy is called in sequence.</li>
</ul>
</div>
<div class="slide">
<h1>Example 3</h1>
<ul><li>example3.pl</li>
</ul>
</div>
<div class="slide">
<h1>Type Constraints</h1>
<pre style="font-size: 65%">
Any
Item
Bool
Maybe['a]
Undef
Defined
Value
Num
Int
Str
ClassName
RoleName
Ref
ScalarRef
ArrayRef['a]
HashRef['a]
CodeRef
RegexpRef
GlobRef
FileHandle
Object
Role
</pre>
</div>
<div class="slide">
<h1>Enum Types</h1>
<ul>
<li>Use the <code>Moose::Util::TypeConstraints</code> module.</li>
<li>define an enum using the <code>enum 'Name' =&gt; qw(values)</code> syntax</li>
<li>Automatically sub-types <code>Str</code></li>
<li>e.g. <code>enum 'AxisName' =&gt; qw(x y z);</code></li>
</ul>
</div>
<div class="slide">
<h1>Custom Types</h1>
<ul>
<li>Use the <code>subtype</code> function to derive from an existing Moose type</li>
<li><em>Note:</em> type names are global to the perl interpreter you're in</li>
<pre>
subtype 'WholeNumber'
=&gt; as 'Int'
=&gt; where { $_ &gt;= 0 };
</pre>
</ul>
</div>
<div class="slide">
<h1>Types in Action</h1>
<ul>
<li>example4.pl</li>
</ul>
</div>
<div class="slide">
<h1>Roles</h1>
<ul>
<li>Encapsulates behaviour or state that can be shared between classes</li>
<li>Reusable behaviour through composition rather than inheritance</li>
<li>Like a "mix-in" or prototypes (javascript); a base-less class</li>
<li>sorta like a pure-abstract class: can't be used on it's own, but is safer to use than with multiple inheritance</li>
<li>Can be used like Java Interfaces (pure definition, no behaviour)</li>
<li>Compile-time and run-time composition</li>
</ul>
</div>
<div class="slide">
<h1>Compile-time Roles</h1>
<ul>
<li>Build the role with <code>use Moose::Role</code> instead of <code>use Moose</code></li>
<li>Then, to include that Role in your class, use the <code>with</code> function</li>
<li>Can't use Roles from Roles</li>
<li>Roles apply in a predictable order; wrappers (later) are applied in the same order as roles</li>
</ul>
</div>
<div class="slide">
<h1>Dynamic composition of Roles</h1>
<ul>
<li>Apply roles to <em>Objects</em> instead of Classes at run-time</li>
<li>Good for Mixins, Plugins or configurable behaviour</li>
</ul>
</div>
<div class="slide">
<h1>Roles in Action</h1>
<ul>
<li>example5.pl</li>
</ul>
</div>
<div class="slide">
<h1>Method Wrappers</h1>
<ul>
<li>A way to predictably and safely augment method behaviour</li>
<li>Very useful in Roles, somewhat useful in regular inheritance</li>
</ul>
</div>
<div class="slide">
<h1>Essential wrappers</h1>
<ul>
<li><code>before</code> run this before a super-class' or -roles' method</li>
<li><code>after</code> run this after a super-class' or -roles' method</li>
<li><code>around</code> run this code around a method</li>
<ul>
<li>passed a code ref to the wrapped method</li>
<li>can alter parameters and results; before/after cannot</li>
</ul>
</ul>
</div>
<div class="slide">
<h1>Essential wrappers in Action</h1>
<ul>
<li>example6.pl</li>
</ul>
</div>
<div class="slide">
<h1>Advanced wrappers</h1>
<ul>
<li><code>override &amp; super</code> bottom-up calling chain</li>
<li><code>augment &amp; inner</code> top-down calling chain</li>
</ul>
</div>
<div class="slide">
<h1>Advanced wrappers in Action</h1>
<ul>
<li>example7.pl</li>
</ul>
</div>
<div class="slide">
<h1>Advanced: "Going Meta"</h1>
<ul>
<li>A way to extend Moose</li>
<li>Change how attributes, methods, storage and other class features behave</li>
<li>Metaclass : Class :: Trait : Role</li>
<li>Good idea to study <code>Class::MOP</code> first</li>
</ul>
</div>
<div class="slide">
<h1>Further Reading</h1>
<ul>
<li><a href='http://users.ox.ac.uk/~oliver/data/files/moose-quick-ref.pdf'>Moose Quick Reference</a></li>
<li>Moose Cookbook on CPAN</li>
<li>MooseX:: extensions on CPAN</li>
<ul>
<li>MooseX::Getopt -- integration with Getopt::Long</li>
<li>MooseX::Singleton -- make your classes work like a singleton</li>
<li>MooseX::Types -- manage your type constraints without naming conflicts</li>
<li>MooseX::Role::Parameterized -- parametric roles sort of like C++ templates or Java generics</li>
</ul>
</ul>
</div>
<div class="slide">
<h1>Q&amp;A</h1>
<ul>
<li>Code and slides: <a href="http://github.com/stash/vanpm-moose/tree/master">http://github.com/stash/vanpm-moose</a>
</ul>
</div>
</div>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.