line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MooX::LazierAttributes; |
2
|
|
|
|
|
|
|
|
3
|
10
|
|
|
9
|
|
403132
|
use strict; |
|
10
|
|
|
|
|
68
|
|
|
10
|
|
|
|
|
270
|
|
4
|
10
|
|
|
9
|
|
1594
|
use warnings; |
|
9
|
|
|
|
|
18
|
|
|
9
|
|
|
|
|
268
|
|
5
|
9
|
|
|
9
|
|
54
|
use Scalar::Util qw/reftype refaddr blessed/; |
|
9
|
|
|
|
|
20
|
|
|
9
|
|
|
|
|
557
|
|
6
|
9
|
|
|
9
|
|
2475
|
use MooX::ReturnModifiers qw/return_modifiers/; |
|
9
|
|
|
|
|
5431
|
|
|
9
|
|
|
|
|
603
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '1.06'; |
9
|
|
|
|
|
|
|
|
10
|
9
|
|
|
9
|
|
70
|
use constant ro => 'ro'; |
|
9
|
|
|
|
|
19
|
|
|
9
|
|
|
|
|
754
|
|
11
|
9
|
|
|
9
|
|
58
|
use constant is_ro => ( is => ro ); |
|
9
|
|
|
|
|
18
|
|
|
9
|
|
|
|
|
492
|
|
12
|
9
|
|
|
9
|
|
53
|
use constant rw => 'rw'; |
|
9
|
|
|
|
|
16
|
|
|
9
|
|
|
|
|
405
|
|
13
|
9
|
|
|
9
|
|
52
|
use constant is_rw => ( is => rw ); |
|
9
|
|
|
|
|
17
|
|
|
9
|
|
|
|
|
432
|
|
14
|
9
|
|
|
9
|
|
62
|
use constant nan => undef; |
|
9
|
|
|
|
|
16
|
|
|
9
|
|
|
|
|
408
|
|
15
|
9
|
|
|
9
|
|
55
|
use constant lzy => ( lazy => 1 ); |
|
9
|
|
|
|
|
19
|
|
|
9
|
|
|
|
|
443
|
|
16
|
9
|
|
|
9
|
|
57
|
use constant bld => ( builder => 1 ); |
|
9
|
|
|
|
|
22
|
|
|
9
|
|
|
|
|
490
|
|
17
|
9
|
|
|
9
|
|
62
|
use constant lzy_bld => ( lazy_build => 1 ); |
|
9
|
|
|
|
|
20
|
|
|
9
|
|
|
|
|
469
|
|
18
|
9
|
|
|
9
|
|
69
|
use constant trg => ( trigger => 1 ); |
|
9
|
|
|
|
|
64
|
|
|
9
|
|
|
|
|
456
|
|
19
|
9
|
|
|
9
|
|
51
|
use constant clr => ( clearer => 1 ); |
|
9
|
|
|
|
|
16
|
|
|
9
|
|
|
|
|
455
|
|
20
|
9
|
|
|
9
|
|
56
|
use constant req => ( required => 1 ); |
|
9
|
|
|
|
|
20
|
|
|
9
|
|
|
|
|
547
|
|
21
|
9
|
|
|
9
|
|
63
|
use constant coe => ( coerce => 1 ); |
|
9
|
|
|
|
|
22
|
|
|
9
|
|
|
|
|
630
|
|
22
|
9
|
|
|
9
|
|
61
|
use constant lzy_hash => ( lazy => 1, default => sub { {} }); |
|
9
|
|
|
|
|
17
|
|
|
9
|
|
|
|
|
625
|
|
|
1
|
|
|
|
|
12612
|
|
23
|
9
|
|
|
9
|
|
55
|
use constant lzy_array => ( lazy => 1, default => sub { [] }); |
|
9
|
|
|
|
|
18
|
|
|
9
|
|
|
|
|
621
|
|
|
0
|
|
|
|
|
0
|
|
24
|
9
|
|
|
9
|
|
57
|
use constant lzy_str => (lazy => 1, default => sub { "" }); |
|
9
|
|
|
|
|
22
|
|
|
9
|
|
|
|
|
605
|
|
|
0
|
|
|
|
|
0
|
|
25
|
9
|
|
|
9
|
|
62
|
use constant dhash => (default => sub { {} }); |
|
9
|
|
|
|
|
20
|
|
|
9
|
|
|
|
|
570
|
|
|
0
|
|
|
|
|
0
|
|
26
|
9
|
|
|
9
|
|
62
|
use constant darray => (default => sub { [] }); |
|
9
|
|
|
|
|
18
|
|
|
9
|
|
|
|
|
638
|
|
|
0
|
|
|
|
|
0
|
|
27
|
9
|
|
|
9
|
|
92
|
use constant dstr => (default => sub { "" }); |
|
9
|
|
|
|
|
40
|
|
|
9
|
|
|
|
|
667
|
|
|
0
|
|
|
|
|
0
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
our %opts; |
30
|
|
|
|
|
|
|
BEGIN { |
31
|
9
|
|
|
9
|
|
3375
|
%opts => (limit => 5, skip => ''); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub import { |
35
|
9
|
|
|
9
|
|
24553
|
my ($package, @export) = @_; |
36
|
9
|
|
|
|
|
31
|
my $target = caller; |
37
|
9
|
|
|
|
|
40
|
my %modifiers = return_modifiers($target); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $attributes = sub { |
40
|
5
|
|
|
5
|
|
57215
|
my @attr = @_; |
41
|
5
|
|
|
|
|
27
|
while (@attr) { |
42
|
31
|
100
|
|
|
|
59658
|
my @names = ref $attr[0] eq 'ARRAY' ? @{ shift @attr } : shift @attr; |
|
3
|
|
|
|
|
11
|
|
43
|
31
|
|
|
|
|
53
|
my @spec = @{ shift(@attr) }; |
|
31
|
|
|
|
|
73
|
|
44
|
|
|
|
|
|
|
|
45
|
31
|
|
|
|
|
64
|
my $eye = scalar @spec - 1; |
46
|
56
|
|
|
|
|
242
|
(grep { ref $spec[$_] eq 'Type::Tiny'} (0 .. $eye)) |
47
|
|
|
|
|
|
|
? push @spec, delete $spec[$eye]->{default} |
48
|
31
|
100
|
66
|
|
|
75
|
: ( ref $spec[$eye] eq 'HASH' && exists $spec[$eye]->{default} ) && splice @spec, ($eye == 0 ? 0 : 1), 0, delete $spec[$eye]->{default}; |
49
|
|
|
|
|
|
|
|
50
|
31
|
|
|
|
|
68
|
for (@names) { |
51
|
36
|
100
|
100
|
|
|
2234
|
unshift @spec, 'set' if $_ =~ m/^\+/ and ( !$spec[0] || $spec[0] ne 'set' ); |
|
|
|
100
|
|
|
|
|
52
|
36
|
100
|
100
|
|
|
221
|
unshift @spec, ro unless ref \$spec[0] eq 'SCALAR' and $spec[0] =~ m/^ro|rw|set$/; |
53
|
36
|
|
|
|
|
100
|
$modifiers{has}->( $_, construct_attribute(@spec) ); |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
} |
56
|
9
|
|
|
|
|
474
|
}; |
57
|
|
|
|
|
|
|
|
58
|
9
|
100
|
|
|
|
38
|
if (ref $export[0]) { |
59
|
1
|
|
|
|
|
4
|
my $o = shift @export; |
60
|
1
|
|
66
|
|
|
13
|
exists $o->{$_} and $opts{$_} = $o->{$_} for (qw/limit skip/); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
{ |
64
|
9
|
|
|
9
|
|
68
|
no strict 'refs'; |
|
9
|
|
|
|
|
17
|
|
|
9
|
|
|
|
|
4577
|
|
|
9
|
|
|
|
|
20
|
|
65
|
104
|
|
|
|
|
275
|
${"${target}::"}{$_} = ${"${package}::"}{$_} |
|
104
|
|
|
|
|
231
|
|
66
|
9
|
100
|
|
|
|
40
|
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
|
9
|
|
|
|
|
22
|
*{"${target}::attributes"} = $attributes; |
|
9
|
|
|
|
|
52
|
|
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
9
|
|
|
|
|
2253
|
return 1; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub construct_attribute { |
74
|
45
|
|
|
45
|
0
|
4299
|
my @spec = @_; |
75
|
45
|
|
|
|
|
77
|
my %attr = (); |
76
|
45
|
100
|
|
|
|
122
|
$attr{is} = $spec[0] unless $spec[0] eq 'set'; |
77
|
|
|
|
|
|
|
|
78
|
45
|
100
|
|
|
|
110
|
if ( ref $spec[1] eq 'Type::Tiny' ) { |
79
|
7
|
|
|
|
|
15
|
$attr{isa} = $spec[1]; |
80
|
7
|
|
|
|
|
15
|
$spec[1] = pop @spec; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
26
|
|
|
26
|
|
36785
|
$attr{default} = ref $spec[1] eq 'CODE' ? $spec[1] : sub { _clone( $spec[1] ) } |
84
|
45
|
100
|
|
|
|
187
|
if defined $spec[1]; |
|
|
100
|
|
|
|
|
|
85
|
|
|
|
|
|
|
|
86
|
45
|
|
|
|
|
78
|
$attr{$_} = $spec[2]->{$_} foreach keys %{ $spec[2] }; |
|
45
|
|
|
|
|
152
|
|
87
|
|
|
|
|
|
|
|
88
|
45
|
|
|
|
|
233
|
return %attr; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub _clone { |
92
|
50
|
|
|
50
|
|
19521
|
my ($to_clone, $recur) = @_; |
93
|
50
|
|
|
|
|
99
|
my $blessed = blessed $to_clone; |
94
|
50
|
50
|
0
|
|
|
110
|
$blessed =~ m/^$opts{skip}$/ and return $to_clone if $opts{skip}; |
95
|
50
|
|
|
|
|
98
|
my $clone = _deep_clone($to_clone, $recur); |
96
|
50
|
100
|
|
|
|
458
|
return $blessed ? bless $clone, $blessed : $clone; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub _deep_clone { |
100
|
53
|
|
|
53
|
|
2106
|
my ($to_clone, $recur) = @_; |
101
|
53
|
|
66
|
|
|
209
|
my $rt = reftype($to_clone) || reftype(\$to_clone); |
102
|
53
|
100
|
|
|
|
151
|
$rt eq 'SCALAR' and return $to_clone; |
103
|
19
|
|
|
|
|
41
|
my $addr = refaddr $to_clone; |
104
|
19
|
50
|
33
|
|
|
82
|
$recur->{$addr}++ && $recur->{$addr} > $opts{limit} and return $to_clone; |
105
|
19
|
100
|
|
|
|
104
|
$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__ |