From: Dave Rolsky Date: Fri, 3 Apr 2009 05:41:20 +0000 (-0500) Subject: doh, forgot to actually add the recipe itself X-Git-Tag: 0.73_01~6 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9ceb6f6a1d5f1566ae994c4b38efa9d0325dca68;p=gitmo%2FMoose.git doh, forgot to actually add the recipe itself --- diff --git a/lib/Moose/Cookbook/Basics/Recipe12.pod b/lib/Moose/Cookbook/Basics/Recipe12.pod new file mode 100644 index 0000000..3ad3282 --- /dev/null +++ b/lib/Moose/Cookbook/Basics/Recipe12.pod @@ -0,0 +1,138 @@ + +=pod + +=begin testing-SETUP + +BEGIN { + eval 'use DateTime; use DateTime::Calendar::Mayan;'; + if ($@) { + diag 'DateTime & DateTime::Calendar::Mayan required for this test'; + ok(1); + exit 0; + } +} + +=end testing-SETUP + +=head1 NAME + +Moose::Cookbook::Basics::Recipe12 - Extending a non-Moose base class + +=head1 SYNOPSIS + + package My::DateTime; + + use Moose; + extends qw( DateTime Moose::Object ); + + use DateTime::Calendar::Mayan; + + has 'mayan_date' => ( + is => 'ro', + isa => 'DateTime::Calendar::Mayan', + init_arg => undef, + lazy => 1, + builder => '_build_mayan_date', + clearer => '_clear_mayan_date', + predicate => 'has_mayan_date', + ); + + sub new { + my $class = shift; + + my $obj = $class->SUPER::new(@_); + + return $class->meta->new_object( + __INSTANCE__ => $obj, + @_, + ); + } + + after 'set' => sub { + $_[0]->_clear_mayan_date; + }; + + sub _build_mayan_date { + DateTime::Calendar::Mayan->from_object( object => $_[0] ); + } + +=head1 DESCRIPTION + +This recipe demonstrates how to use Moose to subclass a parent which +is not Moose based. This recipe only works if the parent class uses a +blessed hash reference for object instances. If your parent is doing +something funkier, you should check out L. + +There are a couple pieces worth noting: + + use Moose; + extends qw( DateTime Moose::Object ); + +First, we C just like we always do. This lets us declare +attributes and use all the Moose sugar to which we are accustomed. + +The C declaration explicitly include L as well +as L. This lets us use methods which are provided by +L, like C. + +The constructor demonstrates a particular hack/pattern (hacktern?) for +working with non-Moose parent classes: + + sub new { + my $class = shift; + + my $obj = $class->SUPER::new(@_); + + return $class->meta->new_object( + __INSTANCE__ => $obj, + @_, + ); + } + +We explicitly call C<< $class->meta->new_object >> and pass the +already-created object in the C<__INSTANCE__> key. Internally, Moose +will take the existing object and initialize any attributes defined in +our subclass. + +The C modifier works just like we'd expect. The fact that +C is defined in our non-Moose parent does not matter. + +=head1 CONCLUSION + +Moose can play nice with non-Moose classes when you follow the pattern +shown here. Your subclass has access to all the power of Moose, +including attribute declaration, method modifiers, type constraints +(for new attributes), and roles. + +However, you won't be able to easily override a parent's "attributes", +since they're not Moose attributes. Nor will you be able to inline a +constructor, since you need to explicitly use the metaclass's object +constructor. + +=head1 AUTHOR + +Dave Rolsky Eautarch@urth.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright 2009 by Infinity Interactive, Inc. + +L + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=begin testing + +my $dt = My::DateTime->new( year => 1970, month => 2, day => 24 ); + +can_ok( $dt, 'mayan_date' ); +isa_ok( $dt->mayan_date, 'DateTime::Calendar::Mayan' ); +is( $dt->mayan_date->date, '12.17.16.9.19', 'got expected mayan date' ); + +$dt->set( year => 2009 ); +ok( ! $dt->has_mayan_date, 'mayan_date is cleared after call to ->set' ); + +=end testing + +=cut