Some more documentation updates.
[gitmo/MooseX-AttributeHelpers.git] / lib / MooseX / AttributeHelpers / MethodProvider.pm
CommitLineData
1b45ecc4 1package MooseX::AttributeHelpers::MethodProvider;
2
3use strict;
4use warnings;
5
6use Carp qw(confess);
7use Exporter qw(import);
8our @EXPORT = qw(get_provider_methods add_method_provider get_provider_type);
9
10our $VERSION = '0.01';
11our $AUTHORITY = 'cpan:STEVAN';
12
13my %REGISTRY;
14
15sub get_provider_type {
16 my $name = shift;
17 return $REGISTRY{$name}->{type} || confess "No provider named $name";
18}
19
20sub get_provider_methods {
21 my ($name, $how) = @_;
22 $how ||= q();
23
24 my $methods = $REGISTRY{$name}->{provides}
25 || confess "No provider named $name";
26
27 if ($how eq ':all') {
28 return $methods;
29 }
30
31 if (ref $how eq 'ARRAY') {
32 return {
33 map {
34 $_ => $methods->{$_} || confess "No factory named $_"
35 } (@$how)
36 };
37 }
38
39 if (ref $how eq 'HASH') {
40 return {
41 map {
42 my ($old, $new) = ($_, $how->{$_});
43 $new => $methods->{$old} || confess "No factory named $old"
44 } (keys %$how)
45 };
46 }
47
48 confess "Don't know to get provider methods by $how";
49}
50
51sub add_method_provider ($;%) {
52 my ($name, %options) = @_;
53
54 confess "Already a method provider named $name"
55 if exists $REGISTRY{$name};
56
57 my $method_map = $options{provides} or confess "No factories provided";
58
59 my $consumes = $options{consumes};
60 foreach my $provider (keys %$consumes) {
61 my $methods = get_provider_methods($provider, $consumes->{$provider});
62 foreach (keys %$methods) {
63 confess "Method $_ already provided" if exists $method_map->{$_};
64 $method_map->{$_} = $methods->{$_};
65 };
66 }
67
68 $REGISTRY{$name} = {
69 type => $options{type} || 'Any',
70 provides => $method_map,
71 };
72}
73
741;
f2b3b8f9 75
76__END__
77
78=pod
79
80=head1 NAME
81
82MooseX::AttributeHelpers::MethodProvider
83
84=head1 SYNOPSIS
85
86 package MooseX::AttributeHelpers::MethodProvider::Counter;
87 use MooseX::AttributeHelpers::MethodProvider;
88
89 add_method_provider 'Counter' => (
90 type => 'Int',
91 provides => {
92 reset => sub {
93 my ($attr, $reader, $writer) = @_;
94 return sub { $writer->($_[0], $attr->default($_[0])) };
95 },
96
97 inc => sub {
98 my ($attr, $reader, $writer) = @_;
99 return sub { $writer->($_[0], $reader->($_[0]) + 1) };
100 },
101
102 dec => sub {
103 my ($attr, $reader, $writer) = @_;
104 return sub { $writer->($_[0], $reader->($_[0]) - 1) };
105 },
106 },
107 );
108
109 1;
110
111=head1 DESCRIPTION
112
113MethodProvider is the interface for new functionality to be added to
114L<MooseX::AttributeHelpers>. The provided metaclasses get their method
115factories from the repository defined by this package. Composite's methods
116are also drawn from here. The package by itself provides no methods, but
117rather functions for creating new entries in the repository - clients are
118encouraged to define new method providers in individual modules (such as
119L<MooseX::AttributeHelpers::MethodProvider::String>) and L<use|perlfunc/use>
120them as desired.
121
122=head1 METHOD SPECIFICATIONS
123
124In add_method_provider as well as get_provider_methods, you can specify a set
125of providers to extract. This can be one of the following:
126
127=over 4
128
129=item ':all'
130
131Causes all methods to be extracted.
132
133=item ArrayRef
134
135Causes the methods named in the ArrayRef to be extracted.
136
137=item HashRef
138
139Causes the methods named by the keys of the hashref to be extracted with the
140names specified by their corresponding value, e.g. C<{inc =&gt; 'my_inc'}>
141
142=back
143
144=head1 EXPORTED FUNCTIONS
145
146=over 4
147
148=item add_method_provider
149
150This is how to define a new method provider. It takes one positional argument
151(the name of the MethodProvider) and three keyword arguments:
152
153=over 4
154
155=item type
156
157A Moose type (such as Maybe[Str]). Validation will be done when applying to
158an attribute to make sure it is this type or a subtype.
159
160=item consumes
161
162A hashref of other method providers (which must be defined, so
163L<use|perlfunc/use> the modules that define them first), of the form
164C<{ProviderName =&gt; Specification}>.
165
166=item provides
167
168A hashref of method names to provide to subrefs. The subs take three
169arguments (an attribute, the attribute's reader, and the attribute's writer)
170and return a new sub that does some action to the attribute.
171
172=back
173
174=item get_provider_methods I<provide_name, specification>
175
176Returns the methods for $provider_name as indicated by $specification.
177
178=item get_provider_type
179
180Returns the type of a method provider.
181
182=back
183
184=head1 BUGS
185
186All complex software has bugs lurking in it, and this module is no
187exception. If you find a bug please either email me, or add the bug
188to cpan-RT.
189
190=head1 AUTHOR
191
192Paul Driver E<lt>frodwith@cpan.orgE<gt>
193
194=cut