Everything works, with my uber hack of making the attribute bits a
[gitmo/MooseX-ClassAttribute.git] / lib / MooseX / ClassAttribute.pm
1 package MooseX::ClassAttribute;
2
3 use strict;
4 use warnings;
5
6 our $VERSION = '0.05';
7 our $AUTHORITY = 'cpan:DROLSKY';
8
9 use Moose ();
10 use Moose::Exporter;
11 use MooseX::ClassAttribute::Role::Meta::Class;
12 use MooseX::ClassAttribute::Role::Meta::Attribute;
13
14 Moose::Exporter->setup_import_methods
15     ( with_caller => [ 'class_has' ] );
16
17
18 sub init_meta
19 {
20     shift;
21     my %p = @_;
22
23     Moose->init_meta(%p);
24
25     return
26         Moose::Util::MetaRole::apply_metaclass_roles
27             ( for_class       => $p{for_class},
28               metaclass_roles => [ 'MooseX::ClassAttribute::Role::Meta::Class' ],
29             );
30 }
31
32 sub class_has
33 {
34     my $caller  = shift;
35     my $name    = shift;
36     my %options = @_;
37
38     my $attrs = ref $name eq 'ARRAY' ? $name : [$name];
39
40     Class::MOP::Class
41             ->initialize($caller)
42             ->add_class_attribute( $_, %options )
43                 for @{ $attrs };
44 }
45
46 1;
47
48 __END__
49
50 =pod
51
52 =head1 NAME
53
54 MooseX::ClassAttribute - Declare class attributes Moose-style
55
56 =head1 SYNOPSIS
57
58     package My::Class;
59
60     use Moose;
61     use MooseX::ClassAttribute;
62
63     class_has 'Cache' =>
64         ( is      => 'rw',
65           isa     => 'HashRef',
66           default => sub { {} },
67         );
68
69     __PACKAGE__->meta()->make_immutable();
70     MooseX::ClassAttribute::container_class()->meta()->make_immutable();
71
72     no Moose;
73     no MooseX::ClassAttribute;
74
75     # then later ...
76
77     My::Class->Cache()->{thing} = ...;
78
79
80 =head1 DESCRIPTION
81
82 This module allows you to declare class attributes in exactly the same
83 way as you declare object attributes, except using C<class_has()>
84 instead of C<has()>. It is also possible to make these attributes
85 immutable (and faster) just as you can with normal Moose attributes.
86
87 You can use any feature of Moose's attribute declarations, including
88 overriding a parent's attributes, delegation (C<handles>), and
89 attribute metaclasses, and it should just work.
90
91 The accessors methods for class attribute may be called on the class
92 directly, or on objects of that class. Passing a class attribute to
93 the constructor will not set it.
94
95 =head1 FUNCTIONS
96
97 This class exports one function when you use it, C<class_has()>. This
98 works exactly like Moose's C<has()>, but it declares class attributes.
99
100 One little nit is that if you include C<no Moose> in your class, you
101 won't remove the C<class_has()> function. To do that you must include
102 C<no MooseX::ClassAttribute> as well.
103
104 If you want to use this module to create class attributes in I<other>
105 classes, you can call the C<process_class_attribute()> function like
106 this:
107
108   MooseX::ClassAttribute::process_class_attribute( $package, ... );
109
110 The first argument is the package which will have the class attribute,
111 and the remaining arguments are the same as those passed to
112 C<class_has()>.
113
114 =head2 Implementation and Immutability
115
116 Underneath the hood, this class creates one new class for each class
117 which has class attributes and sets up delegating methods in the class
118 for which you're creating class attributes. You don't need to worry
119 about this too much, except when it comes to making a class immutable.
120
121 Since the class attributes are not really stored in your class, you
122 need to make the container class immutable as well as your own ...
123
124   __PACKAGE__->meta()->make_immutable();
125   MooseX::ClassAttribute::container_class()->meta()->make_immutable();
126
127 I<This may change in the future!>
128
129 =head1 AUTHOR
130
131 Dave Rolsky, C<< <autarch@urth.org> >>
132
133 =head1 BUGS
134
135 Please report any bugs or feature requests to
136 C<bug-moosex-classattribute@rt.cpan.org>, or through the web interface
137 at L<http://rt.cpan.org>.  I will be notified, and then you'll
138 automatically be notified of progress on your bug as I make changes.
139
140 =head1 COPYRIGHT & LICENSE
141
142 Copyright 2007 Dave Rolsky, All Rights Reserved.
143
144 This program is free software; you can redistribute it and/or modify
145 it under the same terms as Perl itself.
146
147 =cut