Add CAVEAT to Meta::Table_MetaclassTrait about issues when all code is in one file.
[gitmo/Moose.git] / lib / Moose / Cookbook / Meta / Table_MetaclassTrait.pod
CommitLineData
826230c2 1package Moose::Cookbook::Meta::Table_MetaclassTrait;
c5b9daec 2
6d84892d 3# ABSTRACT: Adding a "table" attribute as a metaclass trait
daa0fd7d 4
5__END__
c5b9daec 6
c5b9daec 7
daa0fd7d 8=pod
c5b9daec 9
1910e831 10=begin testing-SETUP
11
12BEGIN {
13 package MyApp::Meta::Class::Trait::HasTable;
14 use Moose::Role;
15
16 has table => (
17 is => 'rw',
18 isa => 'Str',
19 );
20}
21
22=end testing-SETUP
23
c5b9daec 24=head1 SYNOPSIS
25
1910e831 26 # in lib/MyApp/Meta/Class/Trait/HasTable.pm
c5b9daec 27 package MyApp::Meta::Class::Trait::HasTable;
28 use Moose::Role;
29
6a7e3999 30 has table => (
31 is => 'rw',
32 isa => 'Str',
33 );
c5b9daec 34
35 package Moose::Meta::Class::Custom::Trait::HasTable;
36 sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' }
37
1910e831 38 # in lib/MyApp/User.pm
c5b9daec 39 package MyApp::User;
40 use Moose -traits => 'HasTable';
41
fe015af9 42 __PACKAGE__->meta->table('User');
c5b9daec 43
44=head1 DESCRIPTION
45
6d84892d 46In this recipe, we'll create a class metaclass trait which has a "table"
47attribute. This trait is for classes associated with a DBMS table, as one
48might do for an ORM.
c5b9daec 49
6d84892d 50In this example, the table name is just a string, but in a real ORM
51the table might be an object describing the table.
c5b9daec 52
6d84892d 53=head1 THE METACLASS TRAIT
c5b9daec 54
6d84892d 55This really is as simple as the recipe L</SYNOPSIS> shows. The trick is
56getting your classes to use this metaclass, and providing some sort of sugar
57for declaring the table. This is covered in
97da20ef 58L<Moose::Cookbook::Extending::Debugging_BaseClassRole>, which shows how to
59make a module like C<Moose.pm> itself, with sugar like C<has_table()>.
c5b9daec 60
6d84892d 61=head2 Using this Metaclass Trait in Practice
c5b9daec 62
6d84892d 63Accessing this new C<table> attribute is quite simple. Given a class
64named C<MyApp::User>, we could simply write the following:
5377c260 65
6d84892d 66 my $table = MyApp::User->meta->table;
67
68As long as C<MyApp::User> has arranged to apply the
69C<MyApp::Meta::Class::Trait::HasTable> to its metaclass, this method call just
70works. If we want to be more careful, we can check that the class metaclass
71object has a C<table> method:
5377c260 72
73 $table = MyApp::User->meta->table
74 if MyApp::User->meta->can('table');
75
6d84892d 76In theory, this is not entirely correct, since the metaclass might be getting
77its C<table> method from a I<different> trait. In practice, you are unlikely
78to encounter this sort of problem.
5377c260 79
1910e831 80=head1 RECIPE CAVEAT
81
82This recipe doesn't work when you paste it all into a single file. This is
83because the C<< use Moose -traits => 'HasTable'; >> line ends up being
84executed before the C<table> attribute is defined.
85
86When the two packages are separate files, this just works.
87
c5b9daec 88=head1 SEE ALSO
89
b1301316 90L<Moose::Cookbook::Meta::Labeled_AttributeTrait> - Labels implemented via
91attribute traits
c5b9daec 92
c5b9daec 93=pod
1910e831 94
95=begin testing
96
97can_ok( MyApp::User->meta, 'table' );
98is( MyApp::User->meta->table, 'User', 'My::User table is User' );
99
100=end testing