| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Data::Annotation::Overlay; |
|
2
|
3
|
|
|
3
|
|
57
|
use v5.24; |
|
|
3
|
|
|
|
|
11
|
|
|
3
|
3
|
|
|
3
|
|
15
|
use utf8; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
39
|
|
|
4
|
3
|
|
|
3
|
|
754
|
use Moo; |
|
|
3
|
|
|
|
|
10655
|
|
|
|
3
|
|
|
|
|
15
|
|
|
5
|
3
|
|
|
3
|
|
2658
|
use experimental qw< signatures >; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
36
|
|
|
6
|
3
|
|
|
3
|
|
1213
|
use Ouch qw< :trytiny_var >; |
|
|
3
|
|
|
|
|
8221
|
|
|
|
3
|
|
|
|
|
24
|
|
|
7
|
3
|
|
|
3
|
|
421
|
use Scalar::Util qw< blessed >; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
189
|
|
|
8
|
3
|
|
|
3
|
|
29
|
use Data::Annotation::Traverse qw< :all >; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
474
|
|
|
9
|
3
|
|
|
3
|
|
685
|
use namespace::clean; |
|
|
3
|
|
|
|
|
21268
|
|
|
|
3
|
|
|
|
|
23
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
has under => (is => 'ro', required => 1); |
|
12
|
|
|
|
|
|
|
has over => (is => 'ro', default => sub { return {} }); |
|
13
|
|
|
|
|
|
|
has traverse_methods => (is => 'ro', default => 1); |
|
14
|
|
|
|
|
|
|
has strict_blessed => (is => 'ro', default => 0); |
|
15
|
|
|
|
|
|
|
has method_over_key => (is => 'ro', default => 1); |
|
16
|
|
|
|
|
|
|
has value_if_missing => (is => 'ro', predicate => 1); |
|
17
|
|
|
|
|
|
|
has value_if_undef => (is => 'ro', predicate => 1); |
|
18
|
|
|
|
|
|
|
has cache_existing => (is => 'ro', default => 1); |
|
19
|
|
|
|
|
|
|
|
|
20
|
0
|
|
|
0
|
1
|
0
|
sub delete ($self, $path) { $self->set($path, MISSING) } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
11
|
|
|
11
|
1
|
20
|
sub get ($self, $path) { |
|
|
11
|
|
|
|
|
16
|
|
|
|
11
|
|
|
|
|
17
|
|
|
|
11
|
|
|
|
|
16
|
|
|
23
|
11
|
50
|
|
|
|
32
|
ouch 400, 'cannot get an undefined path' unless defined($path); |
|
24
|
11
|
|
|
|
|
35
|
my $crumbs = crumble($path); |
|
25
|
11
|
|
|
|
|
32
|
my $kpath = kpath($crumbs); |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# retrieve item, first look in the overlay, then go down |
|
28
|
11
|
|
|
|
|
22
|
my $retval; |
|
29
|
11
|
|
|
|
|
69
|
my $over = $self->over; |
|
30
|
11
|
|
|
|
|
27
|
my $under = $self->under; |
|
31
|
11
|
|
|
|
|
23
|
my $under_class = blessed($under); |
|
32
|
11
|
50
|
33
|
|
|
49
|
if (exists($over->{$kpath})) { |
|
|
|
50
|
|
|
|
|
|
|
33
|
0
|
|
|
|
|
0
|
$retval = $over->{$kpath}; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
elsif (blessed($under) && $under->isa(__PACKAGE__)) { |
|
36
|
0
|
|
|
|
|
0
|
$retval = $under->get($path); # get from previous layer in stack |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
else { |
|
39
|
11
|
|
|
|
|
36
|
$retval = traverse_plain($under, $crumbs, $self->traversal_options); |
|
40
|
11
|
50
|
|
|
|
56
|
$over->{$kpath} = $retval if $self->cache_existing; |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
11
|
|
|
|
|
31
|
return $self->return_value_for($retval); |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# use traversal options and return value massaging |
|
47
|
0
|
|
|
0
|
1
|
0
|
sub get_external ($self, $path, $data) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
48
|
0
|
0
|
|
|
|
0
|
ouch 400, 'cannot get an undefined path' unless defined($path); |
|
49
|
0
|
|
|
|
|
0
|
my $crumbs = crumble($path); |
|
50
|
0
|
|
|
|
|
0
|
my $retval = traverse_plain($data, $crumbs, $self->traversal_options); |
|
51
|
0
|
|
|
|
|
0
|
return $self->return_value_for($retval); |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
0
|
|
|
0
|
1
|
0
|
sub merged ($self) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
55
|
0
|
|
|
|
|
0
|
my %over; |
|
56
|
0
|
|
|
|
|
0
|
my $cursor = $self; |
|
57
|
0
|
|
|
|
|
0
|
my $any_layer_does_caching = 0; |
|
58
|
0
|
|
|
|
|
0
|
while ('necessary') { |
|
59
|
0
|
|
0
|
|
|
0
|
$any_layer_does_caching ||= $cursor->cache_existing; |
|
60
|
0
|
|
|
|
|
0
|
%over = ($cursor->over->%*, %over); |
|
61
|
0
|
|
|
|
|
0
|
my $under = $cursor->under; |
|
62
|
0
|
0
|
0
|
|
|
0
|
last unless blessed($under) && $under->isa(__PACKAGE__); |
|
63
|
0
|
|
|
|
|
0
|
$cursor = $under; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
# now $cursor points to the bottom of the stack |
|
66
|
0
|
|
|
|
|
0
|
return $self->new( |
|
67
|
|
|
|
|
|
|
under => $cursor->under, |
|
68
|
|
|
|
|
|
|
over => \%over, |
|
69
|
|
|
|
|
|
|
traverse_methods => $cursor->traverse_methods, |
|
70
|
|
|
|
|
|
|
strict_blessed => $cursor->strict_blessed, |
|
71
|
|
|
|
|
|
|
method_over_key => $cursor->method_over_key, |
|
72
|
|
|
|
|
|
|
value_if_missing => $self->value_if_missing, |
|
73
|
|
|
|
|
|
|
value_if_undef => $self->value_if_undef, |
|
74
|
|
|
|
|
|
|
cache_existing => $any_layer_does_caching, |
|
75
|
|
|
|
|
|
|
); |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
11
|
|
|
11
|
1
|
20
|
sub return_value_for ($self, $retval) { |
|
|
11
|
|
|
|
|
18
|
|
|
|
11
|
|
|
|
|
18
|
|
|
|
11
|
|
|
|
|
18
|
|
|
79
|
11
|
50
|
|
|
|
26
|
if (means_missing($retval)) { |
|
80
|
0
|
0
|
|
|
|
0
|
return unless $self->has_value_if_missing; |
|
81
|
0
|
|
|
|
|
0
|
return $self->value_if_missing; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
11
|
50
|
33
|
|
|
70
|
return $retval if defined($retval) || (! $self->has_value_if_undef); |
|
84
|
0
|
|
|
|
|
0
|
return $self->value_if_undef; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
|
|
87
|
0
|
|
|
0
|
1
|
0
|
sub set ($self, $path, $value) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
88
|
0
|
0
|
|
|
|
0
|
ouch 400, 'cannot set an undefined path' unless defined($path); |
|
89
|
0
|
|
|
|
|
0
|
$self->over->{kpath($path)} = $value; |
|
90
|
0
|
|
|
|
|
0
|
return $self; |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
11
|
|
|
11
|
1
|
45
|
sub traversal_options ($self) { |
|
|
11
|
|
|
|
|
21
|
|
|
|
11
|
|
|
|
|
15
|
|
|
94
|
|
|
|
|
|
|
return ( |
|
95
|
11
|
|
|
|
|
66
|
traverse_methods => $self->traverse_methods, |
|
96
|
|
|
|
|
|
|
strict_blessed => $self->strict_blessed, |
|
97
|
|
|
|
|
|
|
method_over_key => $self->method_over_key, |
|
98
|
|
|
|
|
|
|
); |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
1; |