File Coverage

blib/lib/MooseX/AttributeShortcuts/Trait/Role/Attribute.pm
Criterion Covered Total %
statement 18 18 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 26 26 100.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of MooseX-AttributeShortcuts
3             #
4             # This software is Copyright (c) 2017, 2015, 2014, 2013, 2012, 2011 by Chris Weyl.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10             package MooseX::AttributeShortcuts::Trait::Role::Attribute;
11             our $AUTHORITY = 'cpan:RSRCHBOY';
12             $MooseX::AttributeShortcuts::Trait::Role::Attribute::VERSION = '0.036';
13             # ABSTRACT: Role attribute trait to create builder method
14              
15 27     27   186 use MooseX::Role::Parameterized;
  27         64  
  27         248  
16 27     27   230104 use namespace::autoclean 0.24;
  27         732  
  27         210  
17 27     27   2119 use MooseX::Types::Common::String ':all';
  27         60  
  27         411  
18              
19 27     27   129662 use MooseX::Util;
  27         75  
  27         393  
20              
21 27         213 use aliased 'MooseX::AttributeShortcuts::Trait::Role::Method::Builder'
22 27     27   3757 => 'RoleBuilderTrait';
  27         65  
23              
24             with 'MooseX::AttributeShortcuts::Trait::Attribute::HasAnonBuilder';
25              
26              
27             parameter builder_prefix => (isa => NonEmptySimpleStr, default => '_build_');
28              
29              
30              
31             sub builder_method_metaclass {
32 6     6 1 15 my $self = shift @_;
33              
34             # this mirrors the approach taken by
35             # Moose::Meta::Role::Attribute->attribute_for_class()
36 6         31 return with_traits(
37             $self->original_role->method_metaclass,
38             RoleBuilderTrait,
39             );
40             }
41              
42             # no POD, as this is "private". If a role is composed into another role, the
43             # role attributes are cloned into the new role using original_options. In
44             # order to prevent us from installing the same build method twice, we poke at
45             # original_options to ensure the information is propagated correctly.
46             after _set_anon_builder_installed => sub {
47             my $self = shift;
48              
49             $self->original_options->{anon_builder_installed} = 1;
50             return;
51             };
52              
53             after attach_to_role => sub {
54             my ($self, $role) = @_;
55              
56             ### has anon builder?: $self->has_anon_builder
57             return unless $self->has_anon_builder && !$self->anon_builder_installed;
58              
59             ### install our anon builder as a method: $role->name
60             $role->add_method($self->builder => $self->_builder_method_meta($role));
61             $self->_set_anon_builder_installed;
62              
63             return;
64             };
65              
66             role {
67             my $p = shift @_;
68              
69 6     6   38 method canonical_builder_prefix => sub { $p->builder_prefix };
70              
71             around new => sub {
72             # my ($orig, $class) = (shift, shift);
73             my ($orig, $class, $name, %options) = @_;
74              
75             # just pass to the original new() if we don't have an anon builder
76             return $class->$orig($name => %options)
77             unless exists $options{builder} && (ref $options{builder} || q{}) eq 'CODE';
78              
79             # stash anon_builder, set builder => 1
80             $options{anon_builder} = $options{builder};
81             $options{builder} = $class->_mxas_builder_name($name);
82              
83             ### %options
84             ### anon builder: $options{builder}
85             return $class->$orig($name => %options);
86             };
87             };
88              
89             !!42;
90              
91             __END__
92              
93             =pod
94              
95             =encoding UTF-8
96              
97             =for :stopwords Chris Weyl Alders David Etheridge Graham Karen Knop Olaf Steinbrunner
98              
99             =head1 NAME
100              
101             MooseX::AttributeShortcuts::Trait::Role::Attribute - Role attribute trait to create builder method
102              
103             =head1 VERSION
104              
105             This document describes version 0.036 of MooseX::AttributeShortcuts::Trait::Role::Attribute - released October 31, 2017 as part of MooseX-AttributeShortcuts.
106              
107             =head1 DESCRIPTION
108              
109             Normally, attribute options processing takes place at the time an attribute is
110             created and attached to a class, either by virtue of a C<has> statement in a
111             class definition or when a role is applied to a class.
112              
113             This is not an optimal approach for inline builder methods.
114              
115             This is a role attribute trait, to create builder methods when role attributes
116             are created, so that they can be aliased, excluded, etc, like any other role
117             method.
118              
119             =head1 ROLE PARAMETERS
120              
121             Parameterized roles accept parameters that influence their construction. This role accepts the following parameters.
122              
123             =head2 builder_prefix
124              
125             =head1 AROUND METHOD MODIFIERS
126              
127             =head2 new
128              
129             If we have an inline builder defined in our role options, swizzle our options
130             such that C<builder> becomes the builder method name, and C<anon_builder> is
131             the anonymous sub.
132              
133             =head1 AFTER METHOD MODIFIERS
134              
135             =head2 attach_to_role
136              
137             If we have an inline builder defined in our role options, install it as a
138             method.
139              
140             =head1 METHODS
141              
142             =head2 builder_method_metaclass()
143              
144             Returns the metaclass we'll use to install a inline builder.
145              
146             =head1 SEE ALSO
147              
148             Please see those modules/websites for more information related to this module.
149              
150             =over 4
151              
152             =item *
153              
154             L<MooseX::AttributeShortcuts|MooseX::AttributeShortcuts>
155              
156             =back
157              
158             =head1 BUGS
159              
160             Please report any bugs or feature requests on the bugtracker website
161             L<https://github.com/RsrchBoy/moosex-attributeshortcuts/issues>
162              
163             When submitting a bug or request, please include a test-file or a
164             patch to an existing test-file that illustrates the bug or desired
165             feature.
166              
167             =head1 AUTHOR
168              
169             Chris Weyl <cweyl@alumni.drew.edu>
170              
171             =head1 COPYRIGHT AND LICENSE
172              
173             This software is Copyright (c) 2017, 2015, 2014, 2013, 2012, 2011 by Chris Weyl.
174              
175             This is free software, licensed under:
176              
177             The GNU Lesser General Public License, Version 2.1, February 1999
178              
179             =cut