2ae476cbe1eb5c9690e32f694a6894464d81c334
[gitmo/Moose.git] / lib / Moose / Cookbook / Extending / Recipe4.pod
1 package Moose::Cookbook::Extending::Recipe4;
2
3 # ABSTRACT: Acting like Moose.pm and providing sugar Moose-style
4
5 __END__
6
7
8 =pod
9
10 =head1 SYNOPSIS
11
12   package MyApp::Mooseish;
13
14   use Moose ();
15   use Moose::Exporter;
16
17   Moose::Exporter->setup_import_methods(
18       with_meta => ['has_table'],
19       also      => 'Moose',
20   );
21
22   sub init_meta {
23       shift;
24       return Moose->init_meta( @_, metaclass => 'MyApp::Meta::Class' );
25   }
26
27   sub has_table {
28       my $meta = shift;
29       $meta->table(shift);
30   }
31
32   package MyApp::Meta::Class;
33   use Moose;
34
35   extends 'Moose::Meta::Class';
36
37   has 'table' => ( is => 'rw' );
38
39 =head1 DESCRIPTION
40
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.
45
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>.
49
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's appropriate metaclass object is the first argument
53 to the function, so we can do C<S<my $meta = shift;>>.
54
55 See the L<Moose::Exporter> docs for more details on its API.
56
57 =head1 USING MyApp::Mooseish
58
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:
61
62   package MyApp::User;
63
64   use MyApp::Mooseish;
65
66   has_table 'User';
67
68   has 'username' => ( is => 'ro' );
69   has 'password' => ( is => 'ro' );
70
71   sub login { ... }
72
73   no MyApp::Mooseish;
74
75 All of the normal Moose sugar (C<has()>, C<with()>, etc) is available
76 when you C<use MyApp::Mooseish>.
77
78 =head1 CONCLUSION
79
80 Providing sugar functions can make your extension look much more
81 Moose-ish. See L<Fey::ORM> for a more extensive example.
82
83 =begin testing
84
85
86 {
87     package MyApp::User;
88
89     MyApp::Mooseish->import;
90
91     has_table( 'User' );
92
93     has( 'username' => ( is => 'ro' ) );
94     has( 'password' => ( is => 'ro' ) );
95
96     sub login { }
97 }
98
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' );
104
105 =end testing
106
107 =pod