Commit | Line | Data |
f3ce0579 |
1 | |
2 | =pod |
3 | |
4 | =head1 NAME |
5 | |
6 | Moose::Cookbook::Extending::Recipe2 - Providing a role for the base object class |
7 | |
8 | =head1 SYNOPSIS |
9 | |
10 | package MooseX::Debugging; |
11 | |
12 | use strict; |
13 | use warnings; |
14 | |
09167788 |
15 | use Moose (); |
f3ce0579 |
16 | use Moose::Exporter; |
17 | use Moose::Util::MetaRole; |
f3ce0579 |
18 | |
871cda31 |
19 | Moose::Exporter->setup_import_methods; |
f3ce0579 |
20 | |
21 | sub init_meta { |
22 | shift; |
23 | my %options = @_; |
24 | |
a8de959b |
25 | my $meta = Moose->init_meta(%options); |
09167788 |
26 | |
9d72e8c0 |
27 | Moose::Util::MetaRole::apply_base_class_roles( |
f3ce0579 |
28 | for_class => $options{for_class}, |
b51819d6 |
29 | roles => ['MooseX::Debugging::Role::Object'], |
f3ce0579 |
30 | ); |
a8de959b |
31 | |
32 | return $meta; |
f3ce0579 |
33 | } |
34 | |
f3ce0579 |
35 | package MooseX::Debugging::Role::Object; |
36 | |
0df6b748 |
37 | use Moose::Role; |
38 | |
f3ce0579 |
39 | after 'BUILD' => sub { |
40 | my $self = shift; |
41 | |
42 | warn "Made a new " . ref $self . " object\n"; |
6a7e3999 |
43 | }; |
f3ce0579 |
44 | |
45 | =head1 DESCRIPTION |
46 | |
47 | In this example, we provide a role for the base object class that adds |
48 | some simple debugging output. Every time an object is created, it |
49 | spits out a warning saying what type of object it was. |
50 | |
51 | Obviously, a real debugging role would do something more interesting, |
52 | but this recipe is all about how we apply that role. |
53 | |
54 | In this case, with the combination of L<Moose::Exporter> and |
8efdbb91 |
55 | L<Moose::Util::MetaRole>, we ensure that when a module does C<S<use |
56 | MooseX::Debugging>>, it automatically gets the debugging role applied |
f3ce0579 |
57 | to its base object class. |
58 | |
871cda31 |
59 | There are a few pieces of code worth looking at more closely. |
60 | |
61 | Moose::Exporter->setup_import_methods; |
62 | |
63 | This creates an C<import> method in the C<MooseX::Debugging> |
64 | package. Since we are not actually exporting anything, we do not pass |
65 | C<setup_import_methods> any parameters. However, we need to have an |
66 | C<import> method to ensure that our C<init_meta> method is called. |
67 | |
68 | Then in our C<init_meta> method we have this line: |
69 | |
70 | Moose->init_meta(%options); |
71 | |
72 | This is a bit of boilerplate that almost every extension will |
73 | use. This ensures that the caller has a normal Moose metaclass |
74 | I<before> we go and add traits to it. |
75 | |
76 | The C<< Moose->init_meta >> method does ensures that the caller has a |
77 | sane metaclass, and we don't want to replicate that logic in our |
78 | extension. If the C<< Moose->init_meta >> was already called (because |
f08fd992 |
79 | the caller did C<S<use Moose>> before using our extension), then |
80 | calling C<< Moose->init_meta >> again is effectively a no-op. |
871cda31 |
81 | |
f3ce0579 |
82 | =head1 AUTHOR |
83 | |
84 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
85 | |
86 | =head1 COPYRIGHT AND LICENSE |
87 | |
2840a3b2 |
88 | Copyright 2009 by Infinity Interactive, Inc. |
f3ce0579 |
89 | |
90 | L<http://www.iinteractive.com> |
91 | |
92 | This library is free software; you can redistribute it and/or modify |
93 | it under the same terms as Perl itself. |
94 | |
95 | =cut |
96 | |