=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(); Moose::remove_keywords( source => __PACKAGE__, package => $caller, keywords => \@EXPORT, ); 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. This recipe builds on L. Instead of providing our own object base class, we provide our own metaclass class, and we also export a sugar subroutine 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 calls the C function from Moose. This function removes only the keywords exported by this module. More precisely, C removes from the C package the keywords given by the C argument that were created in the C package. 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