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.2206';
3              
4 25     25   14753 use strict;
  25         74  
  25         801  
5 25     25   153 use warnings;
  25         59  
  25         891  
6              
7 25     25   160 use List::Util 1.33 qw( any );
  25         771  
  25         1845  
8 25     25   187 use Moose::Util;
  25         96  
  25         215  
9              
10 25     25   5098 use Moose::Role;
  25         66  
  25         172  
11              
12             with 'Moose::Meta::Method::Accessor::Native';
13              
14             requires '_potential_value';
15              
16             sub _generate_method {
17 529     529   1041 my $self = shift;
18              
19 529         1014 my $inv = '$self';
20 529         2615 my $slot_access = $self->_get_value($inv);
21              
22             return (
23 529         3601 '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   1179 my $self = shift;
33 613         1443 my ($inv, $slot_access) = @_;
34              
35 613         3409 my $potential = $self->_potential_value($slot_access);
36 613         1256 my $old = '@old';
37              
38 613         1065 my @code;
39 613         2029 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       3446 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         1346 push @code, 'my @return;'
50             }
51              
52 613         2457 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         5883 return @code;
64             }
65              
66 474     474   1810 sub _inline_process_arguments { return }
67              
68 391     391   1811 sub _inline_check_arguments { return }
69              
70 256     256   801 sub _inline_coerce_new_values { return }
71              
72             sub _writer_value_needs_copy {
73 512     512   836 my $self = shift;
74              
75 512         1209 return $self->_constraint_must_be_checked;
76             }
77              
78             sub _constraint_must_be_checked {
79 1493     1493   2355 my $self = shift;
80              
81 1493         3655 my $attr = $self->associated_attribute;
82              
83 1493   33     55448 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   3115 my $self = shift;
90 1699         2728 my $type = shift;
91              
92 1699 50 33     12358 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         45623 my $name = $type->name;
103 1699     1867   6916 return any { $name eq $_ } @{ $self->root_types };
  1867         30972  
  1699         5491  
104             }
105             }
106              
107             sub _inline_copy_native_value {
108 613     613   1191 my $self = shift;
109 613         1272 my ($potential_ref) = @_;
110              
111 613 100       2160 return unless $self->_writer_value_needs_copy;
112              
113 167         363 my $code = 'my $potential = ' . ${$potential_ref} . ';';
  167         502  
114              
115 167         323 ${$potential_ref} = '$potential';
  167         342  
116              
117 167         1069 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   2085 sub _inline_capture_return_value { return }
141              
142             sub _inline_set_new_value {
143 613     613   1105 my $self = shift;
144              
145 613 100 100     1623 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         1885 return $self->_inline_optimized_set_new_value(@_);
151             }
152              
153             sub _get_is_lvalue {
154 394     394   771 my $self = shift;
155              
156 394         1036 return $self->associated_attribute->associated_class->instance_metaclass->inline_get_is_lvalue;
157             }
158              
159             sub _inline_optimized_set_new_value {
160 13     13   45 my $self = shift;
161              
162 13         67 return $self->_inline_store_value(@_);
163             }
164              
165             sub _return_value {
166 422     422   750 my $self = shift;
167 422         831 my ($slot_access) = @_;
168              
169 422         1406 return $slot_access;
170             }
171              
172 25     25   271 no Moose::Role;
  25         78  
  25         152  
173              
174             1;