Commit | Line | Data |
6fa0a13f |
1 | |
2 | =pod |
3 | |
4 | =head1 NAME |
5 | |
c8d5f1e1 |
6 | Moose::Cookbook::Extending::Recipe4 - Acting like Moose.pm and providing sugar Moose-style |
6fa0a13f |
7 | |
8 | =head1 SYNOPSIS |
9 | |
10 | package MyApp::Mooseish; |
11 | |
12 | use strict; |
13 | use warnings; |
14 | |
6fa0a13f |
15 | use Moose (); |
554b7648 |
16 | use Moose::Exporter; |
6fa0a13f |
17 | |
aedcb7d9 |
18 | Moose::Exporter->setup_import_methods( |
554b7648 |
19 | with_caller => ['has_table'], |
20 | also => 'Moose', |
21 | ); |
6fa0a13f |
22 | |
554b7648 |
23 | sub init_meta { |
24 | shift; |
a8de959b |
25 | return Moose->init_meta( @_, metaclass => 'MyApp::Meta::Class' ); |
6fa0a13f |
26 | } |
27 | |
28 | sub has_table { |
554b7648 |
29 | my $caller = shift; |
c09fae0b |
30 | $caller->meta->table(shift); |
6fa0a13f |
31 | } |
32 | |
c79239a2 |
33 | package MyApp::Meta::Class; |
34 | use Moose; |
35 | |
36 | extends 'Moose::Meta::Class'; |
37 | |
38 | has 'table' => ( is => 'rw' ); |
39 | |
6fa0a13f |
40 | =head1 DESCRIPTION |
41 | |
554b7648 |
42 | This recipe expands on the use of L<Moose::Exporter> we saw in |
9a8b19be |
43 | L<Moose::Cookbook::Extending::Recipe1>. Instead of providing our own |
44 | object base class, we provide our own metaclass class, and we also |
c09fae0b |
45 | export a C<has_table> sugar function. |
6fa0a13f |
46 | |
47 | Given the above code, you can now replace all instances of C<use |
48 | Moose> with C<use MyApp::Mooseish>. Similarly, C<no Moose> is now |
49 | replaced with C<no MyApp::Mooseish>. |
50 | |
554b7648 |
51 | The C<with_caller> parameter specifies a list of functions that should |
52 | be wrapped before exporting. The wrapper simply ensures that the |
53 | importing package name is the first argument to the function, so we |
54 | can do C<S<my $caller = shift;>>. |
6fa0a13f |
55 | |
554b7648 |
56 | See the L<Moose::Exporter> docs for more details on its API. |
6fa0a13f |
57 | |
554b7648 |
58 | =head1 USING MyApp::Mooseish |
6fa0a13f |
59 | |
60 | The purpose of all this code is to provide a Moose-like |
61 | interface. Here's what it would look like in actual use: |
62 | |
63 | package MyApp::User; |
64 | |
65 | use MyApp::Mooseish; |
66 | |
67 | has_table 'User'; |
68 | |
554b7648 |
69 | has 'username' => ( is => 'ro' ); |
70 | has 'password' => ( is => 'ro' ); |
6fa0a13f |
71 | |
72 | sub login { ... } |
73 | |
74 | no MyApp::Mooseish; |
75 | |
76 | All of the normal Moose sugar (C<has()>, C<with()>, etc) is available |
77 | when you C<use MyApp::Mooseish>. |
78 | |
c09fae0b |
79 | =head1 CONCLUSION |
80 | |
81 | Providing sugar functions can make your extension look much more |
82 | Moose-ish. See L<Fey::ORM> for a more extensive example. |
83 | |
6fa0a13f |
84 | =head1 AUTHOR |
85 | |
86 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
87 | |
88 | =head1 COPYRIGHT AND LICENSE |
89 | |
2840a3b2 |
90 | Copyright 2006-2009 by Infinity Interactive, Inc. |
6fa0a13f |
91 | |
92 | L<http://www.iinteractive.com> |
93 | |
94 | This library is free software; you can redistribute it and/or modify |
95 | it under the same terms as Perl itself. |
96 | |
c79239a2 |
97 | =begin testing |
98 | |
99 | |
100 | { |
101 | package MyApp::User; |
102 | |
103 | MyApp::Mooseish->import; |
104 | |
105 | has_table( 'User' ); |
106 | |
107 | has( 'username' => ( is => 'ro' ) ); |
108 | has( 'password' => ( is => 'ro' ) ); |
109 | |
110 | sub login { } |
111 | } |
112 | |
113 | isa_ok( MyApp::User->meta, 'MyApp::Meta::Class' ); |
114 | is( MyApp::User->meta->table, 'User', |
115 | 'MyApp::User->meta->table returns User' ); |
116 | ok( MyApp::User->can('username'), |
117 | 'MyApp::User has username method' ); |
118 | |
119 | =end testing |
120 | |
6fa0a13f |
121 | =pod |