=pod =head1 NAME Moose::Cookbook::Extending::Recipe2 - Acting like Moose.pm and providing sugar Moose-style =head1 SYNOPSIS package MyApp::Mooseish; use strict; use warnings; our @EXPORT = qw( has_table ); use base 'Exporter'; use Class::MOP; use Moose (); sub import { my $caller = caller(); return if $caller eq 'main'; Moose::init_meta( $caller, undef, # object base class 'MyApp::Meta::Class', ); Moose->import( { into => $caller }, @_ ); __PACKAGE__->export_to_level( 1, @_ ); } sub unimport { my $caller = caller(); no strict 'refs'; foreach my $name (@EXPORT) { if ( defined &{ $caller . '::' . $name } ) { my $keyword = \&{ $caller . '::' . $name }; my ($pkg_name) = Class::MOP::get_code_info($keyword); next if $pkg_name ne __PACKAGE__; delete ${ $caller . '::' }{$name}; } } Moose::unimport( { into_level => 1 } ); } sub has_table { my $caller = caller(); $caller->meta()->table(shift); } =head1 DESCRIPTION The code above shows what it takes to provide an import-based interface just like C. Given the above code, you can now replace all instances of C with C. Similarly, C is now replaced with C. =head1 WARNING This recipe covers a fairly undocumented and ugly part of Moose, and the techniques described here may be deprecated in a future release. If this happens, there will be plenty of warning, as a number of C modules on CPAN already use these techniques. =head1 HOW IT IS USED The purpose of all this code is to provide a Moose-like interface. Here's what it would look like in actual use: package MyApp::User; use MyApp::Mooseish; has_table 'User'; has 'username'; has 'password'; sub login { ... } no MyApp::Mooseish; All of the normal Moose sugar (C, C, etc) is available when you C. =head1 DISSECTION The first bit of magic is the call to C. What this does is create a metaclass for the specified class. Normally, this is called by C in its own C method. However, we can call it first in order to provide an alternate metaclass class. We could also provide an alternate base object class to replace C (see L for an example). The C call takes three parameters. The first is the class for which we are initializing a metaclass object. The second is the base object, which is L by default. The third argument is the metaclass class, which is C by default. The next bit of magic is this: Moose->import( { into => $caller } ); This use of "into" is actually part of the C API, which C uses internally to export things like C and C. Finally, we call C<< __PACKAGE__->export_to_level() >>. This method actually comes from C. This is all a bit fragile since it doesn't stack terribly well. You can basically only have one Moose-alike module. This may be fixed in the still-notional C module someday. The C subroutine is basically a copy of the C from C. You can copy this verbatim into your code. Again, this doesn't stack well. Finally, we have our C subroutine. This provides a bit of sugar that looks a lot like C. =head1 AUTHOR Dave Rolsky Eautarch@urth.orgE =head1 COPYRIGHT AND LICENSE Copyright 2006-2008 by Infinity Interactive, Inc. L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =pod