line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MooX::LazierAttributes; |
2
|
|
|
|
|
|
|
|
3
|
11
|
|
|
10
|
|
524867
|
use strict; |
|
11
|
|
|
|
|
57
|
|
|
11
|
|
|
|
|
247
|
|
4
|
11
|
|
|
10
|
|
1542
|
use warnings; |
|
10
|
|
|
|
|
23
|
|
|
10
|
|
|
|
|
269
|
|
5
|
10
|
|
|
10
|
|
55
|
use Scalar::Util qw/reftype refaddr blessed/; |
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
484
|
|
6
|
10
|
|
|
10
|
|
3713
|
use MooX::ReturnModifiers qw/return_has/; |
|
10
|
|
|
|
|
5257
|
|
|
10
|
|
|
|
|
544
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '1.07'; |
9
|
|
|
|
|
|
|
|
10
|
10
|
|
|
10
|
|
61
|
use constant ro => 'ro'; |
|
10
|
|
|
|
|
20
|
|
|
10
|
|
|
|
|
18093
|
|
11
|
10
|
|
|
10
|
|
64
|
use constant is_ro => ( is => ro ); |
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
464
|
|
12
|
10
|
|
|
10
|
|
47
|
use constant rw => 'rw'; |
|
10
|
|
|
|
|
15
|
|
|
10
|
|
|
|
|
362
|
|
13
|
10
|
|
|
10
|
|
43
|
use constant is_rw => ( is => rw ); |
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
391
|
|
14
|
10
|
|
|
10
|
|
48
|
use constant nan => undef; |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
430
|
|
15
|
10
|
|
|
10
|
|
53
|
use constant lzy => ( lazy => 1 ); |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
458
|
|
16
|
10
|
|
|
10
|
|
55
|
use constant bld => ( builder => 1 ); |
|
10
|
|
|
|
|
40
|
|
|
10
|
|
|
|
|
484
|
|
17
|
10
|
|
|
10
|
|
51
|
use constant lzy_bld => ( lazy_build => 1 ); |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
424
|
|
18
|
10
|
|
|
10
|
|
64
|
use constant trg => ( trigger => 1 ); |
|
10
|
|
|
|
|
46
|
|
|
10
|
|
|
|
|
455
|
|
19
|
10
|
|
|
10
|
|
49
|
use constant clr => ( clearer => 1 ); |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
450
|
|
20
|
10
|
|
|
10
|
|
75
|
use constant req => ( required => 1 ); |
|
10
|
|
|
|
|
21
|
|
|
10
|
|
|
|
|
589
|
|
21
|
10
|
|
|
10
|
|
51
|
use constant coe => ( coerce => 1 ); |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
609
|
|
22
|
10
|
|
|
10
|
|
51
|
use constant lzy_hash => ( lazy => 1, default => sub { {} }); |
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
655
|
|
|
1
|
|
|
|
|
12383
|
|
23
|
10
|
|
|
10
|
|
52
|
use constant lzy_array => ( lazy => 1, default => sub { [] }); |
|
10
|
|
|
|
|
22
|
|
|
10
|
|
|
|
|
682
|
|
|
0
|
|
|
|
|
0
|
|
24
|
10
|
|
|
10
|
|
61
|
use constant lzy_str => (lazy => 1, default => sub { "" }); |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
588
|
|
|
0
|
|
|
|
|
0
|
|
25
|
10
|
|
|
10
|
|
51
|
use constant dhash => (default => sub { {} }); |
|
10
|
|
|
|
|
15
|
|
|
10
|
|
|
|
|
574
|
|
|
0
|
|
|
|
|
0
|
|
26
|
10
|
|
|
10
|
|
52
|
use constant darray => (default => sub { [] }); |
|
10
|
|
|
|
|
18
|
|
|
10
|
|
|
|
|
584
|
|
|
0
|
|
|
|
|
0
|
|
27
|
10
|
|
|
10
|
|
91
|
use constant dstr => (default => sub { "" }); |
|
10
|
|
|
|
|
36
|
|
|
10
|
|
|
|
|
657
|
|
|
0
|
|
|
|
|
0
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
our %opts; |
30
|
|
|
|
|
|
|
BEGIN { |
31
|
10
|
|
|
10
|
|
3269
|
%opts => (limit => 5, skip => ''); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub import { |
35
|
11
|
|
|
11
|
|
29842
|
my ($package, @export) = @_; |
36
|
11
|
|
|
|
|
25
|
my $target = caller; |
37
|
11
|
|
|
|
|
34
|
my $has = return_has($target); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $attributes = sub { |
40
|
5
|
|
|
5
|
|
48204
|
my @attr = @_; |
41
|
5
|
|
|
|
|
19
|
while (@attr) { |
42
|
31
|
100
|
|
|
|
59688
|
my @names = ref $attr[0] eq 'ARRAY' ? @{ shift @attr } : shift @attr; |
|
3
|
|
|
|
|
9
|
|
43
|
31
|
|
|
|
|
40
|
my @spec = @{ shift(@attr) }; |
|
31
|
|
|
|
|
63
|
|
44
|
|
|
|
|
|
|
|
45
|
31
|
|
|
|
|
50
|
my $eye = scalar @spec - 1; |
46
|
56
|
|
|
|
|
200
|
(grep { ref $spec[$_] eq 'Type::Tiny'} (0 .. $eye)) |
47
|
|
|
|
|
|
|
? push @spec, delete $spec[$eye]->{default} |
48
|
31
|
100
|
66
|
|
|
63
|
: ( ref $spec[$eye] eq 'HASH' && exists $spec[$eye]->{default} ) && splice @spec, ($eye == 0 ? 0 : 1), 0, delete $spec[$eye]->{default}; |
49
|
|
|
|
|
|
|
|
50
|
31
|
|
|
|
|
58
|
for (@names) { |
51
|
36
|
100
|
100
|
|
|
2181
|
unshift @spec, 'set' if $_ =~ m/^\+/ and ( !$spec[0] || $spec[0] ne 'set' ); |
|
|
|
100
|
|
|
|
|
52
|
36
|
100
|
100
|
|
|
190
|
unshift @spec, ro unless ref \$spec[0] eq 'SCALAR' and $spec[0] =~ m/^ro|rw|set$/; |
53
|
36
|
|
|
|
|
82
|
$has->( $_, construct_attribute(@spec) ); |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
} |
56
|
11
|
|
|
|
|
321
|
}; |
57
|
|
|
|
|
|
|
|
58
|
11
|
100
|
|
|
|
37
|
if (ref $export[0]) { |
59
|
1
|
|
|
|
|
1
|
my $o = shift @export; |
60
|
1
|
|
66
|
|
|
6
|
exists $o->{$_} and $opts{$_} = $o->{$_} for (qw/limit skip/); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
{ |
64
|
10
|
|
|
10
|
|
84
|
no strict 'refs'; |
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
4548
|
|
|
11
|
|
|
|
|
21
|
|
65
|
132
|
|
|
|
|
273
|
${"${target}::"}{$_} = ${"${package}::"}{$_} |
|
132
|
|
|
|
|
220
|
|
66
|
11
|
100
|
|
|
|
37
|
foreach (scalar @export ? @export : qw/ro is_ro rw is_rw nan lzy bld lzy_bld trg clr req coe lzy_hash lzy_array/); |
67
|
11
|
|
|
|
|
17
|
*{"${target}::attributes"} = $attributes; |
|
11
|
|
|
|
|
50
|
|
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
11
|
|
|
|
|
2374
|
return 1; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub construct_attribute { |
74
|
45
|
|
|
45
|
0
|
3666
|
my @spec = @_; |
75
|
45
|
|
|
|
|
63
|
my %attr = (); |
76
|
45
|
100
|
|
|
|
107
|
$attr{is} = $spec[0] unless $spec[0] eq 'set'; |
77
|
|
|
|
|
|
|
|
78
|
45
|
100
|
|
|
|
90
|
if ( ref $spec[1] eq 'Type::Tiny' ) { |
79
|
7
|
|
|
|
|
12
|
$attr{isa} = $spec[1]; |
80
|
7
|
|
|
|
|
12
|
$spec[1] = pop @spec; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
26
|
|
|
26
|
|
34850
|
$attr{default} = ref $spec[1] eq 'CODE' ? $spec[1] : sub { _clone( $spec[1] ) } |
84
|
45
|
100
|
|
|
|
167
|
if defined $spec[1]; |
|
|
100
|
|
|
|
|
|
85
|
|
|
|
|
|
|
|
86
|
45
|
|
|
|
|
63
|
$attr{$_} = $spec[2]->{$_} foreach keys %{ $spec[2] }; |
|
45
|
|
|
|
|
121
|
|
87
|
|
|
|
|
|
|
|
88
|
45
|
|
|
|
|
173
|
return %attr; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub _clone { |
92
|
50
|
|
|
50
|
|
19157
|
my ($to_clone, $recur) = @_; |
93
|
50
|
|
|
|
|
84
|
my $blessed = blessed $to_clone; |
94
|
50
|
50
|
0
|
|
|
95
|
$blessed =~ m/^$opts{skip}$/ and return $to_clone if $opts{skip}; |
95
|
50
|
|
|
|
|
85
|
my $clone = _deep_clone($to_clone, $recur); |
96
|
50
|
100
|
|
|
|
427
|
return $blessed ? bless $clone, $blessed : $clone; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub _deep_clone { |
100
|
53
|
|
|
53
|
|
1263
|
my ($to_clone, $recur) = @_; |
101
|
53
|
|
66
|
|
|
179
|
my $rt = reftype($to_clone) || reftype(\$to_clone); |
102
|
53
|
100
|
|
|
|
117
|
$rt eq 'SCALAR' and return $to_clone; |
103
|
19
|
|
|
|
|
38
|
my $addr = refaddr $to_clone; |
104
|
19
|
50
|
33
|
|
|
66
|
$recur->{$addr}++ && $recur->{$addr} > $opts{limit} and return $to_clone; |
105
|
19
|
100
|
|
|
|
75
|
$rt eq 'HASH' and return { map +( $_ => _clone( $to_clone->{$_}, $recur ) ), keys %$to_clone }; |
106
|
4
|
50
|
|
|
|
25
|
$rt eq 'ARRAY' and return [ map _clone($_, $recur), @$to_clone ]; |
107
|
0
|
|
|
|
|
|
return $to_clone; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
1; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
__END__ |