1 package MooseX::AttributeHelpers::MethodProvider;
7 use Exporter qw(import);
8 our @EXPORT = qw(get_provider_methods add_method_provider get_provider_type);
10 our $VERSION = '0.01';
11 our $AUTHORITY = 'cpan:STEVAN';
15 sub get_provider_type {
17 return $REGISTRY{$name}->{type} || confess "No provider named $name";
20 sub get_provider_methods {
21 my ($name, $how) = @_;
24 my $methods = $REGISTRY{$name}->{provides}
25 || confess "No provider named $name";
31 if (ref $how eq 'ARRAY') {
34 $_ => $methods->{$_} || confess "No factory named $_"
39 if (ref $how eq 'HASH') {
42 my ($old, $new) = ($_, $how->{$_});
43 $new => $methods->{$old} || confess "No factory named $old"
48 confess "Don't know to get provider methods by $how";
51 sub add_method_provider ($;%) {
52 my ($name, %options) = @_;
54 confess "Already a method provider named $name"
55 if exists $REGISTRY{$name};
57 my $method_map = $options{provides} or confess "No factories provided";
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->{$_};
69 type => $options{type} || 'Any',
70 provides => $method_map,
82 MooseX::AttributeHelpers::MethodProvider
86 package MooseX::AttributeHelpers::MethodProvider::Counter;
87 use MooseX::AttributeHelpers::MethodProvider;
89 add_method_provider 'Counter' => (
93 my ($attr, $reader, $writer) = @_;
94 return sub { $writer->($_[0], $attr->default($_[0])) };
98 my ($attr, $reader, $writer) = @_;
99 return sub { $writer->($_[0], $reader->($_[0]) + 1) };
103 my ($attr, $reader, $writer) = @_;
104 return sub { $writer->($_[0], $reader->($_[0]) - 1) };
113 MethodProvider is the interface for new functionality to be added to
114 L<MooseX::AttributeHelpers>. The provided metaclasses get their method
115 factories from the repository defined by this package. Composite's methods
116 are also drawn from here. The package by itself provides no methods, but
117 rather functions for creating new entries in the repository - clients are
118 encouraged to define new method providers in individual modules (such as
119 L<MooseX::AttributeHelpers::MethodProvider::String>) and L<use|perlfunc/use>
122 =head1 METHOD SPECIFICATIONS
124 In add_method_provider as well as get_provider_methods, you can specify a set
125 of providers to extract. This can be one of the following:
131 Causes all methods to be extracted.
135 Causes the methods named in the ArrayRef to be extracted.
139 Causes the methods named by the keys of the hashref to be extracted with the
140 names specified by their corresponding value, e.g. C<{inc => 'my_inc'}>
144 =head1 EXPORTED FUNCTIONS
148 =item add_method_provider
150 This is how to define a new method provider. It takes one positional argument
151 (the name of the MethodProvider) and three keyword arguments:
157 A Moose type (such as Maybe[Str]). Validation will be done when applying to
158 an attribute to make sure it is this type or a subtype.
162 A hashref of other method providers (which must be defined, so
163 L<use|perlfunc/use> the modules that define them first), of the form
164 C<{ProviderName => Specification}>.
168 A hashref of method names to provide to subrefs. The subs take three
169 arguments (an attribute, the attribute's reader, and the attribute's writer)
170 and return a new sub that does some action to the attribute.
174 =item get_provider_methods I<provide_name, specification>
176 Returns the methods for $provider_name as indicated by $specification.
178 =item get_provider_type
180 Returns the type of a method provider.
186 All complex software has bugs lurking in it, and this module is no
187 exception. If you find a bug please either email me, or add the bug
192 Paul Driver E<lt>frodwith@cpan.orgE<gt>