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.2205';
3              
4 25     25   16023 use strict;
  25         69  
  25         848  
5 25     25   158 use warnings;
  25         64  
  25         1009  
6              
7 25     25   204 use List::Util 1.33 qw( any );
  25         877  
  25         2082  
8 25     25   227 use Moose::Util;
  25         75  
  25         209  
9              
10 25     25   5227 use Moose::Role;
  25         61  
  25         188  
11              
12             with 'Moose::Meta::Method::Accessor::Native';
13              
14             requires '_potential_value';
15              
16             sub _generate_method {
17 529     529   1029 my $self = shift;
18              
19 529         1037 my $inv = '$self';
20 529         2733 my $slot_access = $self->_get_value($inv);
21              
22             return (
23 529         3420 '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   1231 my $self = shift;
33 613         1342 my ($inv, $slot_access) = @_;
34              
35 613         3365 my $potential = $self->_potential_value($slot_access);
36 613         1223 my $old = '@old';
37              
38 613         1024 my @code;
39 613         2152 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       3285 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         1285 push @code, 'my @return;'
50             }
51              
52 613         2365 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         6109 return @code;
64             }
65              
66 474     474   1724 sub _inline_process_arguments { return }
67              
68 391     391   1744 sub _inline_check_arguments { return }
69              
70 256     256   792 sub _inline_coerce_new_values { return }
71              
72             sub _writer_value_needs_copy {
73 512     512   774 my $self = shift;
74              
75 512         1194 return $self->_constraint_must_be_checked;
76             }
77              
78             sub _constraint_must_be_checked {
79 1493     1493   2402 my $self = shift;
80              
81 1493         3691 my $attr = $self->associated_attribute;
82              
83 1493   33     55928 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   3216 my $self = shift;
90 1699         2617 my $type = shift;
91              
92 1699 50 33     12558 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         45988 my $name = $type->name;
103 1699     1867   7219 return any { $name eq $_ } @{ $self->root_types };
  1867         31536  
  1699         5578  
104             }
105             }
106              
107             sub _inline_copy_native_value {
108 613     613   1208 my $self = shift;
109 613         1241 my ($potential_ref) = @_;
110              
111 613 100       2238 return unless $self->_writer_value_needs_copy;
112              
113 167         378 my $code = 'my $potential = ' . ${$potential_ref} . ';';
  167         536  
114              
115 167         307 ${$potential_ref} = '$potential';
  167         294  
116              
117 167         1082 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   2270 sub _inline_capture_return_value { return }
141              
142             sub _inline_set_new_value {
143 613     613   1200 my $self = shift;
144              
145 613 100 100     1726 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         1759 return $self->_inline_optimized_set_new_value(@_);
151             }
152              
153             sub _get_is_lvalue {
154 394     394   851 my $self = shift;
155              
156 394         1008 return $self->associated_attribute->associated_class->instance_metaclass->inline_get_is_lvalue;
157             }
158              
159             sub _inline_optimized_set_new_value {
160 13     13   49 my $self = shift;
161              
162 13         62 return $self->_inline_store_value(@_);
163             }
164              
165             sub _return_value {
166 422     422   834 my $self = shift;
167 422         811 my ($slot_access) = @_;
168              
169 422         1425 return $slot_access;
170             }
171              
172 25     25   257 no Moose::Role;
  25         77  
  25         187  
173              
174             1;