1 package MooseX::AttributeHelpers::MethodProvider;
7 our $AUTHORITY = 'cpan:STEVAN';
10 use Exporter qw(import);
11 our @EXPORT = qw(get_provider_methods add_method_provider get_provider_type);
13 our $VERSION = '0.01';
14 our $AUTHORITY = 'cpan:STEVAN';
18 sub get_provider_type {
20 return $REGISTRY{$name}->{type} || confess "No provider named $name";
23 sub get_provider_methods {
24 my ($name, $how) = @_;
27 my $methods = $REGISTRY{$name}->{provides}
28 || confess "No provider named $name";
34 if (ref $how eq 'ARRAY') {
37 $_ => $methods->{$_} || confess "No factory named $_"
42 if (ref $how eq 'HASH') {
45 my ($old, $new) = ($_, $how->{$_});
46 $new => $methods->{$old} || confess "No factory named $old"
51 confess "Don't know to get provider methods by $how";
54 sub add_method_provider ($;%) {
55 my ($name, %options) = @_;
57 confess "Already a method provider named $name"
58 if exists $REGISTRY{$name};
60 my $method_map = $options{provides} or confess "No factories provided";
62 my $consumes = $options{consumes};
63 foreach my $provider (keys %$consumes) {
64 my $methods = get_provider_methods($provider, $consumes->{$provider});
65 foreach (keys %$methods) {
66 confess "Method $_ already provided" if exists $method_map->{$_};
67 $method_map->{$_} = $methods->{$_};
72 type => $options{type} || 'Any',
73 provides => $method_map,
85 MooseX::AttributeHelpers::MethodProvider
89 package MooseX::AttributeHelpers::MethodProvider::Counter;
90 use MooseX::AttributeHelpers::MethodProvider;
92 add_method_provider 'Counter' => (
96 my ($attr, $reader, $writer) = @_;
97 return sub { $writer->($_[0], $attr->default($_[0])) };
101 my ($attr, $reader, $writer) = @_;
102 return sub { $writer->($_[0], $reader->($_[0]) + 1) };
106 my ($attr, $reader, $writer) = @_;
107 return sub { $writer->($_[0], $reader->($_[0]) - 1) };
116 MethodProvider is the interface for new functionality to be added to
117 L<MooseX::AttributeHelpers>. The provided metaclasses get their method
118 factories from the repository defined by this package. Composite's methods
119 are also drawn from here. The package by itself provides no methods, but
120 rather functions for creating new entries in the repository - clients are
121 encouraged to define new method providers in individual modules (such as
122 L<MooseX::AttributeHelpers::MethodProvider::String>) and L<use|perlfunc/use>
125 =head1 METHOD SPECIFICATIONS
127 In add_method_provider as well as get_provider_methods, you can specify a set
128 of providers to extract. This can be one of the following:
134 Causes all methods to be extracted.
138 Causes the methods named in the ArrayRef to be extracted.
142 Causes the methods named by the keys of the hashref to be extracted with the
143 names specified by their corresponding value, e.g. C<{inc => 'my_inc'}>
147 =head1 EXPORTED FUNCTIONS
151 =item add_method_provider
153 This is how to define a new method provider. It takes one positional argument
154 (the name of the MethodProvider) and three keyword arguments:
160 A Moose type (such as Maybe[Str]). Validation will be done when applying to
161 an attribute to make sure it is this type or a subtype.
165 A hashref of other method providers (which must be defined, so
166 L<use|perlfunc/use> the modules that define them first), of the form
167 C<{ProviderName => Specification}>.
171 A hashref of method names to provide to subrefs. The subs take three
172 arguments (an attribute, the attribute's reader, and the attribute's writer)
173 and return a new sub that does some action to the attribute.
177 =item get_provider_methods I<provide_name, specification>
179 Returns the methods for $provider_name as indicated by $specification.
181 =item get_provider_type
183 Returns the type of a method provider.
189 All complex software has bugs lurking in it, and this module is no
190 exception. If you find a bug please either email me, or add the bug
195 Paul Driver E<lt>frodwith@cpan.orgE<gt>