Moose::Cookbook::Basics::Recipe11 - Extending a non-Moose base class
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] ); }
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 MooseX::InsideOut.
You might also want to check out MooseX::NonMoose, which does all the grunt work for you.
There are a couple pieces worth noting:
use Moose; extends qw( DateTime Moose::Object );
First, we use Moose just like we always do. This lets us declare attributes and use all the Moose sugar to which we are accustomed.
use Moose
The extends declaration explicitly include Moose::Object as well as DateTime. This lets us use methods which are provided by Moose::Object, like does.
extends
does
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 $class->meta->new_object and pass the already-created object in the __INSTANCE__ key. Internally, Moose will take the existing object and initialize any attributes defined in our subclass.
$class->meta->new_object
__INSTANCE__
The after modifier works just like we'd expect. The fact that set is defined in our non-Moose parent does not matter.
after
set
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.
Dave Rolsky <autarch@urth.org>
Copyright 2009-2010 by Infinity Interactive, Inc.
http://www.iinteractive.com
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Moose, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Moose
CPAN shell
perl -MCPAN -e shell install Moose
For more information on module installation, please visit the detailed CPAN module installation guide.