Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / Moose / Cookbook / Basics / Recipe11.pod
1
2 =pod
3
4 =begin testing-SETUP
5
6 BEGIN {
7     eval 'use DateTime; use DateTime::Calendar::Mayan;';
8     if ($@) {
9         diag 'DateTime & DateTime::Calendar::Mayan required for this test';
10         ok(1);
11         exit 0;
12     }
13 }
14
15 =end testing-SETUP
16
17 =head1 NAME
18
19 Moose::Cookbook::Basics::Recipe11 - Extending a non-Moose base class
20
21 =head1 SYNOPSIS
22
23   package My::DateTime;
24
25   use Moose;
26   extends qw( DateTime Moose::Object );
27
28   use DateTime::Calendar::Mayan;
29
30   has 'mayan_date' => (
31       is        => 'ro',
32       isa       => 'DateTime::Calendar::Mayan',
33       init_arg  => undef,
34       lazy      => 1,
35       builder   => '_build_mayan_date',
36       clearer   => '_clear_mayan_date',
37       predicate => 'has_mayan_date',
38   );
39
40   sub new {
41       my $class = shift;
42
43       my $obj = $class->SUPER::new(@_);
44
45       return $class->meta->new_object(
46           __INSTANCE__ => $obj,
47           @_,
48       );
49   }
50
51   after 'set' => sub {
52       $_[0]->_clear_mayan_date;
53   };
54
55   sub _build_mayan_date {
56       DateTime::Calendar::Mayan->from_object( object => $_[0] );
57   }
58
59 =head1 DESCRIPTION
60
61 This recipe demonstrates how to use Moose to subclass a parent which
62 is not Moose based. This recipe only works if the parent class uses a
63 blessed hash reference for object instances. If your parent is doing
64 something funkier, you should check out L<MooseX::InsideOut>.
65
66 You might also want to check out L<MooseX::NonMoose>, which does all
67 the grunt work for you.
68
69 There are a couple pieces worth noting:
70
71   use Moose;
72   extends qw( DateTime Moose::Object );
73
74 First, we C<use Moose> just like we always do. This lets us declare
75 attributes and use all the Moose sugar to which we are accustomed.
76
77 The C<extends> declaration explicitly include L<Moose::Object> as well
78 as L<DateTime>. This lets us use methods which are provided by
79 L<Moose::Object>, like C<does>.
80
81 The constructor demonstrates a particular hack/pattern (hacktern?) for
82 working with non-Moose parent classes:
83
84   sub new {
85       my $class = shift;
86
87       my $obj = $class->SUPER::new(@_);
88
89       return $class->meta->new_object(
90           __INSTANCE__ => $obj,
91           @_,
92       );
93   }
94
95 We explicitly call C<< $class->meta->new_object >> and pass the
96 already-created object in the C<__INSTANCE__> key. Internally, Moose
97 will take the existing object and initialize any attributes defined in
98 our subclass.
99
100 The C<after> modifier works just like we'd expect. The fact that
101 C<set> is defined in our non-Moose parent does not matter.
102
103 =head1 CONCLUSION
104
105 Moose can play nice with non-Moose classes when you follow the pattern
106 shown here. Your subclass has access to all the power of Moose,
107 including attribute declaration, method modifiers, type constraints
108 (for new attributes), and roles.
109
110 However, you won't be able to easily override a parent's "attributes",
111 since they're not Moose attributes. Nor will you be able to inline a
112 constructor, since you need to explicitly use the metaclass's object
113 constructor.
114
115 =head1 AUTHOR
116
117 Dave Rolsky E<lt>autarch@urth.orgE<gt>
118
119 =head1 COPYRIGHT AND LICENSE
120
121 Copyright 2009 by Infinity Interactive, Inc.
122
123 L<http://www.iinteractive.com>
124
125 This library is free software; you can redistribute it and/or modify
126 it under the same terms as Perl itself.
127
128 =begin testing
129
130 my $dt = My::DateTime->new( year => 1970, month => 2, day => 24 );
131
132 can_ok( $dt, 'mayan_date' );
133 isa_ok( $dt->mayan_date, 'DateTime::Calendar::Mayan' );
134 is( $dt->mayan_date->date, '12.17.16.9.19', 'got expected mayan date' );
135
136 $dt->set( year => 2009 );
137 ok( ! $dt->has_mayan_date, 'mayan_date is cleared after call to ->set' );
138
139 =end testing
140
141 =cut