File Coverage

blib/lib/MooseX/AttributeTags.pm
Criterion Covered Total %
statement 46 48 95.8
branch 7 14 50.0
condition 2 5 40.0
subroutine 14 14 100.0
pod n/a
total 69 81 85.1


line stmt bran cond sub pod time code
1 1     1   553958 use 5.008;
  1         5  
2 1     1   6 use strict;
  1         2  
  1         20  
3 1     1   6 use warnings;
  1         2  
  1         76  
4              
5             package MooseX::AttributeTags;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.005';
9              
10 1     1   7 use Carp;
  1         2  
  1         77  
11 1     1   8 use Data::OptList qw(mkopt);
  1         3  
  1         10  
12 1     1   133 use Scalar::Util qw(blessed);
  1         2  
  1         333  
13              
14             my $subname = eval { require Sub::Name; 'Sub::Name'->can('subname') }
15             || do { require Sub::Util; 'Sub::Util'->can('set_subname') };
16              
17             my $yah = 1; # avoid exported subs becoming constants
18              
19             sub import
20             {
21 1     1   13 my $caller = caller;
22 1         2 my $class = shift;
23 1         4 my $opts = mkopt(\@_);
24 1         58 my $prole = $class->_prole;
25            
26 1         12 for (@$opts)
27             {
28 3         13 my ($traitname, $traitdesc) = @$_;
29 3   100     17 $traitdesc ||= [];
30 3 50       11 ref($traitdesc) eq 'ARRAY'
31             or croak("Expected arrayref, not $traitdesc; stopped");
32            
33 3         4 my %attrs;
34 3         12 my $inner_opts = mkopt($traitdesc);
35 3         122 for (@$inner_opts)
36             {
37 4         9 my ($attrname, $attrdesc) = @$_;
38 4         19 $attrs{$attrname} = $class->_canonicalize_attribute_spec($attrdesc);
39             }
40            
41 3         14 my $traitqname = sprintf('%s::%s', $caller, $traitname);
42 3         17 my $trait = $prole->generate_role(
43             package => $traitqname,
44             parameters => { attributes => \%attrs },
45             );
46            
47 3 50   5   263 my $coderef = $subname->($traitqname, sub () { $traitqname if $yah });
  5     5   75516  
        5      
        5      
48 1     1   8 no strict 'refs';
  1         5  
  1         250  
49 3         183 *$traitqname = $coderef;
50             }
51             }
52              
53             sub _prole
54             {
55 1     1   406 require MooseX::AttributeTags::PRole;
56 1         6 Class::MOP::class_of('MooseX::AttributeTags::PRole');
57             }
58              
59             sub _canonicalize_attribute_spec
60             {
61 4     4   7 shift;
62 4         7 my $spec = $_[0];
63            
64 4 50       9 return [ is => 'ro' ]
65             unless defined $spec;
66            
67 4 100       20 return $spec
68             if ref $spec eq 'ARRAY';
69            
70 1 50       5 return [ %$spec ]
71             if ref $spec eq 'HASH';
72            
73 1 50       15 return [ is => 'ro', lazy => 1, default => $spec ]
74             if ref $spec eq 'CODE';
75            
76 0 0 0       return [ is => 'ro', isa => $spec ]
77             if blessed($spec) && $spec->isa('Moose::Meta::TypeConstraint');
78            
79 0           croak("Expected coderef/arrayref/hashref/constraint, not $spec; stopped");
80             }
81              
82             1;
83              
84             __END__
85              
86             =pod
87              
88             =encoding utf-8
89              
90             =head1 NAME
91              
92             MooseX::AttributeTags - tag your Moose attributes
93              
94             =head1 SYNOPSIS
95              
96             package User;
97            
98             use Moose;
99             use MooseX::Types::Moose 'Bool';
100             use MooseX::AttributeTags (
101             SerializationStyle => [
102             hidden => Bool,
103             ],
104             );
105            
106             has username => (
107             traits => [ SerializationStyle ],
108             is => 'ro',
109             hidden => 0,
110             );
111            
112             has password => (
113             traits => [ SerializationStyle ],
114             is => 'rw',
115             hidden => 1,
116             );
117              
118             =head1 DESCRIPTION
119              
120             MooseX::AttributeTags is a factory for attribute traits. All the work is
121             done in the import method.
122              
123             =head2 Methods
124              
125             =over
126              
127             =item C<< import(@optlist) >>
128              
129             The option list is a list of trait names to create (which will be exported
130             to the caller package as constants).
131              
132             Each trait name may be optionally followed by an arrayref of attributes to
133             be created within the trait. (In the SYNOPSIS, the "SerializationStyle" trait
134             gets an attribute called "hidden".)
135              
136             Each attribute may be optionally followed by I<one> of:
137              
138             =over
139              
140             =item *
141              
142             A coderef which provides a default value for the attribute.
143              
144             =item *
145              
146             A type constraint object (such as those provided by Types::Standard or
147             MooseX::Types; not a type constraint string) to validate the attribute.
148              
149             =item *
150              
151             An arrayref or hashref providing options similar to those given to
152             Moose's C<has> keyword.
153              
154             =back
155              
156             =back
157              
158             Note that in the SYNOPSIS example, a constant C<< User::SerializationStyle >>
159             is defined.
160              
161             my $attr = User->meta->get_attribute('username');
162             $attr->does(User::SerializationStyle); # true
163             $attr->hidden; # false
164              
165             =head1 BUGS
166              
167             Please report any bugs to
168             L<http://rt.cpan.org/Dist/Display.html?Queue=MooseX-AttributeTags>.
169              
170             =head1 SEE ALSO
171              
172             L<Moose>.
173              
174             =head1 AUTHOR
175              
176             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
177              
178             =head1 COPYRIGHT AND LICENCE
179              
180             This software is copyright (c) 2013, 2017, 2019 by Toby Inkster.
181              
182             This is free software; you can redistribute it and/or modify it under
183             the same terms as the Perl 5 programming language system itself.
184              
185             =head1 DISCLAIMER OF WARRANTIES
186              
187             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
188             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
189             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
190