Commit | Line | Data |
cb235596 |
1 | package Moose::Cookbook::Legacy::Debugging_BaseClassReplacement; |
2 | |
3 | # ABSTRACT: Providing an alternate base object class |
4 | |
5 | |
6 | |
7 | =pod |
8 | |
9 | =head1 NAME |
10 | |
11 | Moose::Cookbook::Extending::Recipe3 - Providing an alternate base object class |
12 | |
13 | =head1 VERSION |
14 | |
15 | version 2.0402 |
16 | |
17 | =head1 SYNOPSIS |
18 | |
19 | package MyApp::Base; |
20 | use Moose; |
21 | |
22 | extends 'Moose::Object'; |
23 | |
24 | before 'new' => sub { warn "Making a new " . $_[0] }; |
25 | |
26 | no Moose; |
27 | |
28 | package MyApp::UseMyBase; |
29 | use Moose (); |
30 | use Moose::Exporter; |
31 | |
32 | Moose::Exporter->setup_import_methods( also => 'Moose' ); |
33 | |
34 | sub init_meta { |
35 | shift; |
36 | return Moose->init_meta( @_, base_class => 'MyApp::Base' ); |
37 | } |
38 | |
39 | =head1 DESCRIPTION |
40 | |
41 | B<WARNING: Replacing the base class entirely, as opposed to applying roles to |
42 | the base class, is strongly discouraged. This recipe is provided solely for |
43 | reference when encountering older code that does this.> |
44 | |
45 | A common extension is to provide an alternate base class. One way to |
46 | do that is to make a C<MyApp::Base> and add C<S<extends |
47 | 'MyApp::Base'>> to every class in your application. That's pretty |
48 | tedious. Instead, you can create a Moose-alike module that sets the |
49 | base object class to C<MyApp::Base> for you. |
50 | |
51 | Then, instead of writing C<S<use Moose>> you can write C<S<use |
52 | MyApp::UseMyBase>>. |
53 | |
54 | In this particular example, our base class issues some debugging |
55 | output every time a new object is created, but you can think of some |
56 | more interesting things to do with your own base class. |
57 | |
58 | This uses the magic of L<Moose::Exporter>. When we call C<< |
59 | Moose::Exporter->setup_import_methods( also => 'Moose' ) >> it builds |
60 | C<import> and C<unimport> methods for you. The C<< also => 'Moose' >> |
61 | bit says that we want to export everything that Moose does. |
62 | |
63 | The C<import> method that gets created will call our C<init_meta> |
64 | method, passing it C<< for_caller => $caller >> as its |
65 | arguments. The C<$caller> is set to the class that actually imported |
66 | us in the first place. |
67 | |
68 | See the L<Moose::Exporter> docs for more details on its API. |
69 | |
70 | =for testing-SETUP use Test::Requires { |
71 | 'Test::Output' => '0', |
72 | }; |
73 | |
74 | =head1 USING MyApp::UseMyBase |
75 | |
76 | To actually use our new base class, we simply use C<MyApp::UseMyBase> |
77 | I<instead> of C<Moose>. We get all the Moose sugar plus our new base |
78 | class. |
79 | |
80 | package Foo; |
81 | |
82 | use MyApp::UseMyBase; |
83 | |
84 | has 'size' => ( is => 'rw' ); |
85 | |
86 | no MyApp::UseMyBase; |
87 | |
88 | =head1 CONCLUSION |
89 | |
90 | This is an awful lot of magic for a simple base class. You will often |
91 | want to combine a metaclass trait with a base class extension, and |
92 | that's when this technique is useful. |
93 | |
94 | =begin testing |
95 | |
96 | { |
97 | package Foo; |
98 | |
99 | MyApp::UseMyBase->import; |
100 | |
101 | has( 'size' => ( is => 'rw' ) ); |
102 | } |
103 | |
104 | ok( Foo->isa('MyApp::Base'), 'Foo isa MyApp::Base' ); |
105 | |
106 | ok( Foo->can('size'), 'Foo has a size method' ); |
107 | |
108 | my $foo; |
109 | stderr_like( |
110 | sub { $foo = Foo->new( size => 2 ) }, |
111 | qr/^Making a new Foo/, |
112 | 'got expected warning when calling Foo->new' |
113 | ); |
114 | |
115 | is( $foo->size(), 2, '$foo->size is 2' ); |
116 | |
117 | =end testing |
118 | |
119 | =head1 AUTHOR |
120 | |
121 | Moose is maintained by the Moose Cabal, along with the help of many contributors. See L<Moose/CABAL> and L<Moose/CONTRIBUTORS> for details. |
122 | |
123 | =head1 COPYRIGHT AND LICENSE |
124 | |
125 | This software is copyright (c) 2012 by Infinity Interactive, Inc.. |
126 | |
127 | This is free software; you can redistribute it and/or modify it under |
128 | the same terms as the Perl 5 programming language system itself. |
129 | |
130 | =cut |
131 | |
132 | |
133 | __END__ |
134 | |