6 Moose::Cookbook::Extending::Recipe2 - Acting like Moose.pm and providing sugar Moose-style
10 package MyApp::Mooseish;
15 our @EXPORT = qw( has_table );
22 my $caller = caller();
24 return if $caller eq 'main';
28 undef, # object base class
32 Moose->import( { into => $caller }, @_ );
34 __PACKAGE__->export_to_level( 1, @_ );
38 my $caller = caller();
40 Moose::remove_keywords(
41 source => __PACKAGE__,
46 Moose->unimport( { into_level => 1 } );
50 my $caller = caller();
52 $caller->meta()->table(shift);
57 The code above shows what it takes to provide an import-based
58 interface just like C<Moose.pm>. This recipe builds on
59 L<Moose::Cookbook::Extending::Recipe1>. Instead of providing our own
60 object base class, we provide our own metaclass class, and we also
61 export a sugar subroutine C<has_table()>.
63 Given the above code, you can now replace all instances of C<use
64 Moose> with C<use MyApp::Mooseish>. Similarly, C<no Moose> is now
65 replaced with C<no MyApp::Mooseish>.
69 This recipe covers a fairly undocumented and ugly part of Moose, and
70 the techniques described here may be deprecated in a future
71 release. If this happens, there will be plenty of warning, as a number
72 of C<MooseX> modules on CPAN already use these techniques.
76 The purpose of all this code is to provide a Moose-like
77 interface. Here's what it would look like in actual use:
92 All of the normal Moose sugar (C<has()>, C<with()>, etc) is available
93 when you C<use MyApp::Mooseish>.
97 The first bit of magic is the call to C<Moose::init_meta()>. What this
98 does is create a metaclass for the specified class. Normally, this is
99 called by C<Moose.pm> in its own C<import()> method. However, we can
100 call it first in order to provide an alternate metaclass class. We
101 could also provide an alternate base object class to replace
102 C<Moose::Object> (see L<Moose::Cookbook::Extending::Recipe1> for an
105 The C<Moose::init_meta()> call takes three parameters. The first is
106 the class for which we are initializing a metaclass object. The second
107 is the base object, which is L<Moose::Object> by default. The third
108 argument is the metaclass class, which is C<Moose::Meta::Class> by
111 The next bit of magic is this:
113 Moose->import( { into => $caller } );
115 This use of "into" is actually part of the C<Sub::Exporter> API, which
116 C<Moose.pm> uses internally to export things like C<has()> and
119 Finally, we call C<< __PACKAGE__->export_to_level() >>. This method
120 actually comes from C<Exporter>.
122 This is all a bit fragile since it doesn't stack terribly well. You
123 can basically only have one Moose-alike module. This may be fixed in
124 the still-notional C<MooseX::Exporter> module someday.
126 The C<unimport()> subroutine calls the C<remove_keywords> function
127 from Moose. This function removes only the keywords exported by
128 this module. More precisely, C<remove_keywords> removes from the
129 C<package> package the keywords given by the C<keywords> argument
130 that were created in the C<source> package.
132 Finally, we have our C<has_table()> subroutine. This provides a bit of
133 sugar that looks a lot like C<has()>.
137 Dave Rolsky E<lt>autarch@urth.orgE<gt>
139 =head1 COPYRIGHT AND LICENSE
141 Copyright 2006-2008 by Infinity Interactive, Inc.
143 L<http://www.iinteractive.com>
145 This library is free software; you can redistribute it and/or modify
146 it under the same terms as Perl itself.