1 package Moose::Cookbook::Extending::Recipe4;
3 # ABSTRACT: Acting like Moose.pm and providing sugar Moose-style
12 package MyApp::Mooseish;
17 Moose::Exporter->setup_import_methods(
18 with_meta => ['has_table'],
24 return Moose->init_meta( @_, metaclass => 'MyApp::Meta::Class' );
32 package MyApp::Meta::Class;
35 extends 'Moose::Meta::Class';
37 has 'table' => ( is => 'rw' );
41 This recipe expands on the use of L<Moose::Exporter> we saw in
42 L<Moose::Cookbook::Extending::Recipe1>. Instead of providing our own
43 object base class, we provide our own metaclass class, and we also
44 export a C<has_table> sugar function.
46 Given the above code, you can now replace all instances of C<use
47 Moose> with C<use MyApp::Mooseish>. Similarly, C<no Moose> is now
48 replaced with C<no MyApp::Mooseish>.
50 The C<with_meta> parameter specifies a list of functions that should
51 be wrapped before exporting. The wrapper simply ensures that the
52 importing package name is the first argument to the function, so we
53 can do C<S<my $caller = shift;>>.
55 See the L<Moose::Exporter> docs for more details on its API.
57 =head1 USING MyApp::Mooseish
59 The purpose of all this code is to provide a Moose-like
60 interface. Here's what it would look like in actual use:
68 has 'username' => ( is => 'ro' );
69 has 'password' => ( is => 'ro' );
75 All of the normal Moose sugar (C<has()>, C<with()>, etc) is available
76 when you C<use MyApp::Mooseish>.
80 Providing sugar functions can make your extension look much more
81 Moose-ish. See L<Fey::ORM> for a more extensive example.
89 MyApp::Mooseish->import;
93 has( 'username' => ( is => 'ro' ) );
94 has( 'password' => ( is => 'ro' ) );
99 isa_ok( MyApp::User->meta, 'MyApp::Meta::Class' );
100 is( MyApp::User->meta->table, 'User',
101 'MyApp::User->meta->table returns User' );
102 ok( MyApp::User->can('username'),
103 'MyApp::User has username method' );