File Coverage

blib/lib/Moose/Meta/Method/Accessor/Native/Writer.pm
Criterion Covered Total %
statement 66 70 94.2
branch 7 8 87.5
condition 9 15 60.0
subroutine 21 22 95.4
pod n/a
total 103 115 89.5


line stmt bran cond sub pod time code
1             package Moose::Meta::Method::Accessor::Native::Writer;
2             our $VERSION = '2.2203';
3              
4 25     25   12955 use strict;
  25         63  
  25         729  
5 25     25   132 use warnings;
  25         60  
  25         797  
6              
7 25     25   135 use List::Util 1.33 qw( any );
  25         652  
  25         1743  
8 25     25   152 use Moose::Util;
  25         66  
  25         175  
9              
10 25     25   4492 use Moose::Role;
  25         51  
  25         139  
11              
12             with 'Moose::Meta::Method::Accessor::Native';
13              
14             requires '_potential_value';
15              
16             sub _generate_method {
17 529     529   876 my $self = shift;
18              
19 529         880 my $inv = '$self';
20 529         2042 my $slot_access = $self->_get_value($inv);
21              
22             return (
23 529         2897 'sub {',
24             'my ' . $inv . ' = shift;',
25             $self->_inline_curried_arguments,
26             $self->_inline_writer_core($inv, $slot_access),
27             '}',
28             );
29             }
30              
31             sub _inline_writer_core {
32 613     613   1041 my $self = shift;
33 613         1210 my ($inv, $slot_access) = @_;
34              
35 613         2478 my $potential = $self->_potential_value($slot_access);
36 613         1108 my $old = '@old';
37              
38 613         971 my @code;
39 613         1750 push @code, (
40             $self->_inline_check_argument_count,
41             $self->_inline_process_arguments($inv, $slot_access),
42             $self->_inline_check_arguments('for writer'),
43             $self->_inline_check_lazy($inv, '$type_constraint', '$type_coercion', '$type_message'),
44             );
45              
46 613 100       2500 if ($self->_return_value($slot_access)) {
47             # some writers will save the return value in this variable when they
48             # generate the potential value.
49 572         1093 push @code, 'my @return;'
50             }
51              
52 613         1946 push @code, (
53             $self->_inline_coerce_new_values,
54             $self->_inline_copy_native_value(\$potential),
55             $self->_inline_tc_code($potential, '$type_constraint', '$type_coercion', '$type_message'),
56             $self->_inline_get_old_value_for_trigger($inv, $old),
57             $self->_inline_capture_return_value($slot_access),
58             $self->_inline_set_new_value($inv, $potential, $slot_access),
59             $self->_inline_trigger($inv, $slot_access, $old),
60             $self->_inline_return_value($slot_access, 'for writer'),
61             );
62              
63 613         5136 return @code;
64             }
65              
66 474     474   1345 sub _inline_process_arguments { return }
67              
68 391     391   1461 sub _inline_check_arguments { return }
69              
70 256     256   676 sub _inline_coerce_new_values { return }
71              
72             sub _writer_value_needs_copy {
73 512     512   729 my $self = shift;
74              
75 512         1009 return $self->_constraint_must_be_checked;
76             }
77              
78             sub _constraint_must_be_checked {
79 1493     1493   2160 my $self = shift;
80              
81 1493         3163 my $attr = $self->associated_attribute;
82              
83 1493   33     47766 return $attr->has_type_constraint
84             && ( !$self->_is_root_type( $attr->type_constraint )
85             || ( $attr->should_coerce && $attr->type_constraint->has_coercion ) );
86             }
87              
88             sub _is_root_type {
89 1699     1699   2720 my $self = shift;
90 1699         2280 my $type = shift;
91              
92 1699 50 33     10728 if ( blessed($type)
      33        
93             && $type->can('does')
94             && $type->does('Specio::Constraint::Role::Interface') )
95             {
96 0         0 require Specio::Library::Builtins;
97             return
98 0     0   0 any { $type->is_same_type_as( Specio::Library::Builtins::t($_) ) }
99 0         0 @{ $self->root_types };
  0         0  
100             }
101             else {
102 1699         39359 my $name = $type->name;
103 1699     1867   5988 return any { $name eq $_ } @{ $self->root_types };
  1867         26920  
  1699         4687  
104             }
105             }
106              
107             sub _inline_copy_native_value {
108 613     613   1039 my $self = shift;
109 613         1137 my ($potential_ref) = @_;
110              
111 613 100       1855 return unless $self->_writer_value_needs_copy;
112              
113 167         292 my $code = 'my $potential = ' . ${$potential_ref} . ';';
  167         428  
114              
115 167         235 ${$potential_ref} = '$potential';
  167         255  
116              
117 167         659 return $code;
118             }
119              
120             around _inline_tc_code => sub {
121             my $orig = shift;
122             my $self = shift;
123             my ($value, $tc, $coercion, $message, $for_lazy) = @_;
124              
125             return unless $for_lazy || $self->_constraint_must_be_checked;
126              
127             return $self->$orig(@_);
128             };
129              
130             around _inline_check_constraint => sub {
131             my $orig = shift;
132             my $self = shift;
133             my ($value, $tc, $message, $for_lazy) = @_;
134              
135             return unless $for_lazy || $self->_constraint_must_be_checked;
136              
137             return $self->$orig(@_);
138             };
139              
140 593     593   1868 sub _inline_capture_return_value { return }
141              
142             sub _inline_set_new_value {
143 613     613   975 my $self = shift;
144              
145 613 100 100     1445 return $self->_inline_store_value(@_)
      100        
146             if $self->_writer_value_needs_copy
147             || !$self->_slot_access_can_be_inlined
148             || !$self->_get_is_lvalue;
149              
150 331         1438 return $self->_inline_optimized_set_new_value(@_);
151             }
152              
153             sub _get_is_lvalue {
154 394     394   688 my $self = shift;
155              
156 394         935 return $self->associated_attribute->associated_class->instance_metaclass->inline_get_is_lvalue;
157             }
158              
159             sub _inline_optimized_set_new_value {
160 13     13   47 my $self = shift;
161              
162 13         53 return $self->_inline_store_value(@_);
163             }
164              
165             sub _return_value {
166 422     422   619 my $self = shift;
167 422         718 my ($slot_access) = @_;
168              
169 422         1157 return $slot_access;
170             }
171              
172 25     25   202 no Moose::Role;
  25         74  
  25         119  
173              
174             1;