line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MooX::Struct; |
2
|
|
|
|
|
|
|
|
3
|
16
|
|
|
16
|
|
1078499
|
use 5.008; |
|
16
|
|
|
|
|
170
|
|
4
|
16
|
|
|
16
|
|
82
|
use strict; |
|
16
|
|
|
|
|
45
|
|
|
16
|
|
|
|
|
441
|
|
5
|
16
|
|
|
16
|
|
82
|
use warnings; |
|
16
|
|
|
|
|
29
|
|
|
16
|
|
|
|
|
499
|
|
6
|
16
|
|
|
16
|
|
9800
|
use utf8; |
|
16
|
|
|
|
|
227
|
|
|
16
|
|
|
|
|
76
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
BEGIN { |
9
|
16
|
|
|
16
|
|
725
|
$MooX::Struct::AUTHORITY = 'cpan:TOBYINK'; |
10
|
16
|
|
|
|
|
346
|
$MooX::Struct::VERSION = '0.018'; |
11
|
|
|
|
|
|
|
} |
12
|
|
|
|
|
|
|
|
13
|
16
|
|
|
16
|
|
8690
|
use Moo 1.000; |
|
16
|
|
|
|
|
176476
|
|
|
16
|
|
|
|
|
94
|
|
14
|
16
|
|
|
16
|
|
30640
|
use Types::TypeTiny 1.000 qw( HashLike ArrayLike ); |
|
16
|
|
|
|
|
50577
|
|
|
16
|
|
|
|
|
92
|
|
15
|
16
|
|
|
16
|
|
72788
|
use Types::Standard 1.000 qw( HashRef ArrayRef Num Ref ); |
|
16
|
|
|
|
|
1113935
|
|
|
16
|
|
|
|
|
173
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $HashLike = HashLike | Ref['HASH']; |
18
|
|
|
|
|
|
|
my $ArrayLike = ArrayLike | Ref['ARRAY']; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use overload |
21
|
|
|
|
|
|
|
q[""] => 'TO_STRING', |
22
|
11
|
|
|
11
|
|
1679
|
q[bool] => sub { 1 }, |
23
|
16
|
|
|
|
|
143
|
q[@{}] => 'TO_ARRAY', |
24
|
|
|
|
|
|
|
q[=] => 'CLONE', |
25
|
16
|
|
|
16
|
|
19562
|
fallback => 1; |
|
16
|
|
|
|
|
45
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
METHODS: { |
28
|
16
|
|
|
16
|
|
1778
|
no warnings; |
|
16
|
|
|
|
|
37
|
|
|
16
|
|
|
|
|
5924
|
|
29
|
7
|
|
|
7
|
1
|
5521
|
sub OBJECT_ID { require Object::ID; goto \&Object::ID::object_id }; |
|
7
|
|
|
|
|
18161
|
|
30
|
24
|
|
|
24
|
1
|
86
|
sub FIELDS { qw() }; |
31
|
1
|
|
|
1
|
1
|
25
|
sub TYPE { +undef }; |
32
|
14
|
|
|
14
|
1
|
63
|
sub TO_ARRAY { [ map {; $_[0]->$_ } $_[0]->FIELDS ] }; |
|
37
|
|
|
|
|
311
|
|
33
|
2
|
|
|
2
|
1
|
7
|
sub TO_HASH { +{ map {; $_ => $_[0]->$_ } $_[0]->FIELDS } }; |
|
6
|
|
|
|
|
55
|
|
34
|
12
|
|
|
12
|
1
|
435
|
sub TO_STRING { join q[ ], @{ $_[0]->TO_ARRAY } }; |
|
12
|
|
|
|
|
32
|
|
35
|
2
|
|
|
2
|
|
549
|
sub CLONE { my $s = shift; ref($s)->new(%{$s->TO_HASH}, @_) }; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
20
|
|
36
|
6
|
50
|
|
6
|
1
|
82
|
sub CLASSNAME { ref($_[0]) or $_[0] }; |
37
|
6
|
|
|
6
|
1
|
8296
|
sub TYPE_TINY { Types::Standard::InstanceOf->parameterize(shift->CLASSNAME) }; |
38
|
|
|
|
|
|
|
}; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub BUILDARGS |
41
|
|
|
|
|
|
|
{ |
42
|
67
|
|
|
67
|
1
|
50157
|
my $class = shift; |
43
|
67
|
|
|
|
|
188
|
my @fields = $class->FIELDS; |
44
|
|
|
|
|
|
|
|
45
|
67
|
100
|
100
|
|
|
597
|
if ( |
|
|
100
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
46
|
|
|
|
|
|
|
(@_==1 and ref $_[0] eq 'ARRAY') or # optimized usual case |
47
|
|
|
|
|
|
|
(@_==1 and ArrayLike->check($_[0]) and not $HashLike->check($_[0])) |
48
|
|
|
|
|
|
|
) |
49
|
|
|
|
|
|
|
{ |
50
|
30
|
|
|
|
|
97
|
my @values = @{ $_[0] }; |
|
30
|
|
|
|
|
70
|
|
51
|
30
|
100
|
|
|
|
237
|
Carp::confess("too many values passed to constructor (expected @fields); stopped") |
52
|
|
|
|
|
|
|
unless @fields >= @values; |
53
|
16
|
|
|
16
|
|
122
|
no warnings; |
|
16
|
|
|
|
|
36
|
|
|
16
|
|
|
|
|
9767
|
|
54
|
|
|
|
|
|
|
return +{ |
55
|
|
|
|
|
|
|
map { |
56
|
29
|
|
|
|
|
166
|
$fields[$_] => $values[$_]; |
|
55
|
|
|
|
|
606
|
|
57
|
|
|
|
|
|
|
} 0 .. $#values |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
elsif (@_ == 1 and ref $_[0] ne 'HASH' and $HashLike->check($_[0])) |
62
|
|
|
|
|
|
|
{ |
63
|
|
|
|
|
|
|
# help Moo::Object! |
64
|
1
|
|
|
|
|
200
|
@_ = +{ %{$_[0]} }; |
|
1
|
|
|
|
|
27
|
|
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
37
|
|
|
|
|
921
|
my $hashref = $class->SUPER::BUILDARGS(@_); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# my %tmp = map { $_ => 1 } keys %$hashref; |
70
|
|
|
|
|
|
|
# delete $tmp{$_} for @fields; |
71
|
|
|
|
|
|
|
# if (my @unknown = sort keys %tmp) |
72
|
|
|
|
|
|
|
# { |
73
|
|
|
|
|
|
|
# Carp::confess("unknown keys passed to constructor (@unknown); stopped"); |
74
|
|
|
|
|
|
|
# } |
75
|
|
|
|
|
|
|
|
76
|
36
|
|
|
|
|
826
|
return $hashref; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub EXTEND |
80
|
|
|
|
|
|
|
{ |
81
|
4
|
|
|
4
|
|
191
|
my ($invocant, @args) = @_; |
82
|
4
|
|
|
|
|
7
|
my $base = $invocant; |
83
|
4
|
100
|
|
|
|
14
|
$base = ref $invocant if ref $invocant; |
84
|
|
|
|
|
|
|
|
85
|
4
|
|
|
|
|
98
|
my $processor = 'MooX::Struct::Processor'->new; |
86
|
4
|
|
|
|
|
97
|
while (@args) { |
87
|
5
|
100
|
|
|
|
20
|
last unless $args[0] =~ /^-(.+)$/; |
88
|
1
|
|
|
|
|
7
|
$processor->flags->{ lc($1) } = !!shift @args; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
4
|
|
|
|
|
8
|
my $subname = undef; |
92
|
4
|
50
|
|
|
|
11
|
$subname = ${ shift @args } if ref($args[0]) eq 'SCALAR'; |
|
4
|
|
|
|
|
9
|
|
93
|
|
|
|
|
|
|
|
94
|
4
|
|
|
|
|
17
|
my $new_class = $processor->make_sub( |
95
|
|
|
|
|
|
|
$subname, |
96
|
|
|
|
|
|
|
[ -extends => [$base], @args ], |
97
|
|
|
|
|
|
|
)->(); |
98
|
4
|
100
|
|
|
|
18
|
return $new_class unless ref $invocant; |
99
|
|
|
|
|
|
|
|
100
|
2
|
|
|
|
|
8
|
bless $invocant => $new_class; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
my $done = 0; |
104
|
|
|
|
|
|
|
sub _data_printer |
105
|
|
|
|
|
|
|
{ |
106
|
0
|
|
|
0
|
|
0
|
my ($self, $ddp) = @_; |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
0
|
my @values; |
109
|
|
|
|
|
|
|
my $label; |
110
|
|
|
|
|
|
|
|
111
|
0
|
0
|
|
|
|
0
|
if ($Data::Printer::VERSION lt '0.90') { |
112
|
0
|
|
|
|
|
0
|
require Data::Printer::Filter; |
113
|
0
|
|
|
|
|
0
|
require Term::ANSIColor; |
114
|
0
|
|
|
|
|
0
|
@values = map scalar(&Data::Printer::p(\$_, return_value => 'dump')), @$self; |
115
|
0
|
|
0
|
|
|
0
|
$label = Term::ANSIColor::colored($self->TYPE||'struct', 'bright_yellow'); |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
else |
118
|
|
|
|
|
|
|
{ |
119
|
0
|
|
|
|
|
0
|
@values = map $ddp->parse(\$_), @$self; |
120
|
0
|
|
0
|
|
|
0
|
$label = $ddp->maybe_colorize($self->TYPE||'struct', 'MooX::Struct', 'bright_yellow'); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
0
|
0
|
|
|
|
0
|
if (grep /\n/, @values) { |
124
|
|
|
|
|
|
|
return sprintf( |
125
|
|
|
|
|
|
|
"%s[\n\t%s,\n]", |
126
|
|
|
|
|
|
|
$label, |
127
|
0
|
|
|
|
|
0
|
join(qq[,\n\t], map { s/\n/\n\t/gm; $_ } @values), |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
128
|
|
|
|
|
|
|
); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
0
|
sprintf('%s[ %s ]', $label, join q[, ], @values); |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
0
|
|
|
|
|
0
|
BEGIN { |
135
|
|
|
|
|
|
|
package MooX::Struct::Processor; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
{ |
138
|
16
|
|
|
16
|
|
148
|
no warnings; |
|
16
|
|
|
16
|
|
34
|
|
|
16
|
|
|
|
|
2109
|
|
|
16
|
|
|
|
|
79
|
|
139
|
16
|
|
|
|
|
244
|
our $AUTHORITY = 'cpan:TOBYINK'; |
140
|
16
|
|
|
|
|
38
|
our $VERSION = '0.018'; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
38
|
|
|
38
|
|
75
|
sub _uniq { my %seen; grep { not $seen{$_}++ } @_ }; |
|
38
|
|
|
|
|
102
|
|
|
73
|
|
|
|
|
279
|
|
144
|
|
|
|
|
|
|
|
145
|
16
|
|
|
16
|
|
130
|
use Moo 1.000; |
|
16
|
|
|
|
|
318
|
|
|
16
|
|
|
|
|
214
|
|
146
|
16
|
|
|
16
|
|
6578
|
use Exporter::Tiny qw(); |
|
16
|
|
|
|
|
53
|
|
|
16
|
|
|
|
|
752
|
|
147
|
16
|
|
|
16
|
|
151
|
use Types::TypeTiny 1.000 qw( TypeTiny CodeLike HashLike ArrayLike ); |
|
16
|
|
|
|
|
310
|
|
|
16
|
|
|
|
|
132
|
|
148
|
16
|
|
|
16
|
|
7207
|
use Types::Standard 1.000 qw( HashRef ArrayRef CodeRef Num ); |
|
16
|
|
|
|
|
225
|
|
|
16
|
|
|
|
|
97
|
|
149
|
16
|
|
|
16
|
|
13257
|
use Carp qw(confess); |
|
16
|
|
|
|
|
34
|
|
|
16
|
|
|
|
|
993
|
|
150
|
16
|
|
|
16
|
|
105
|
use Scalar::Util qw(blessed); |
|
16
|
|
|
|
|
43
|
|
|
16
|
|
|
|
|
777
|
|
151
|
16
|
|
|
16
|
|
8295
|
use namespace::clean qw(); |
|
16
|
|
|
|
|
187894
|
|
|
16
|
|
|
|
|
436
|
|
152
|
16
|
|
|
16
|
|
116
|
use B::Hooks::EndOfScope qw(on_scope_end); |
|
16
|
|
|
|
|
33
|
|
|
16
|
|
|
|
|
113
|
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub __install_sub__ ($) { |
155
|
114
|
|
|
114
|
|
204
|
my $args = shift; |
156
|
114
|
|
|
|
|
290
|
my ($pkg, $name, $code) = @$args{qw(into as code)}; |
157
|
16
|
|
|
16
|
|
1712
|
no strict 'refs'; |
|
16
|
|
|
|
|
36
|
|
|
16
|
|
|
|
|
35157
|
|
158
|
114
|
|
|
|
|
158
|
*{"$pkg\::$name"} = $code; |
|
114
|
|
|
|
|
732
|
|
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
has flags => ( |
162
|
|
|
|
|
|
|
is => 'ro', |
163
|
|
|
|
|
|
|
isa => HashLike, |
164
|
28
|
|
|
|
|
1093
|
default => sub { +{} }, |
165
|
16
|
|
|
|
|
177
|
); |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
has class_map => ( |
168
|
|
|
|
|
|
|
is => 'ro', |
169
|
|
|
|
|
|
|
isa => HashLike, |
170
|
32
|
|
|
|
|
1688
|
default => sub { +{} }, |
171
|
16
|
|
|
|
|
331688
|
); |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
has base => ( |
174
|
|
|
|
|
|
|
is => 'ro', |
175
|
31
|
|
|
|
|
48878
|
default => sub { 'MooX::Struct' }, |
176
|
16
|
|
|
|
|
8217
|
); |
177
|
|
|
|
|
|
|
|
178
|
16
|
|
|
|
|
4523
|
has trace => ( |
179
|
|
|
|
|
|
|
is => 'lazy', |
180
|
|
|
|
|
|
|
); |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub _build_trace |
183
|
|
|
|
|
|
|
{ |
184
|
|
|
|
|
|
|
$ENV{PERL_MOOX_STRUCT_TRACE} |
185
|
27
|
100
|
|
27
|
|
641
|
or shift->flags->{trace}; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
16
|
|
|
|
|
12739
|
has trace_handle => ( |
189
|
|
|
|
|
|
|
is => 'lazy', |
190
|
|
|
|
|
|
|
); |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub _build_trace_handle |
193
|
|
|
|
|
|
|
{ |
194
|
1
|
|
|
1
|
|
65
|
require IO::Handle; |
195
|
1
|
|
|
|
|
9
|
\*STDERR; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
16
|
|
|
|
|
12395
|
my $counter = 0; |
199
|
|
|
|
|
|
|
sub create_class |
200
|
|
|
|
|
|
|
{ |
201
|
39
|
|
|
39
|
0
|
103
|
my ($self, $opts) = @_; |
202
|
39
|
|
|
|
|
62
|
my $klass; |
203
|
39
|
|
|
|
|
99
|
for my $o (@$opts) { |
204
|
73
|
100
|
|
|
|
203
|
next unless $o->[0] eq '-class'; |
205
|
4
|
100
|
|
|
|
30
|
$klass = ArrayRef->check($o->[1]) ? join('::', @{$o->[1]}) : ${$o->[1]}; |
|
1
|
|
|
|
|
71
|
|
|
3
|
|
|
|
|
135
|
|
206
|
4
|
|
|
|
|
36
|
last; |
207
|
|
|
|
|
|
|
} |
208
|
39
|
100
|
|
|
|
329
|
$klass = sprintf('%s::__ANON__::%04d', $self->base, ++$counter) unless defined $klass; |
209
|
39
|
|
|
|
|
282
|
"Moo"->_set_superclasses($klass, $self->base); |
210
|
39
|
|
|
|
|
6612
|
"Moo"->_maybe_reset_handlemoose($klass); |
211
|
39
|
100
|
|
|
|
1222
|
if ($self->trace) |
212
|
|
|
|
|
|
|
{ |
213
|
2
|
|
|
|
|
49
|
$self->trace_handle->printf( |
214
|
|
|
|
|
|
|
"package %s;\nuse Moo;\n", |
215
|
|
|
|
|
|
|
$klass, |
216
|
|
|
|
|
|
|
); |
217
|
|
|
|
|
|
|
} |
218
|
39
|
|
|
|
|
242
|
return $klass; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub process_meta |
222
|
|
|
|
|
|
|
{ |
223
|
20
|
|
|
20
|
0
|
115
|
my ($self, $klass, $name, $val) = @_; |
224
|
|
|
|
|
|
|
|
225
|
20
|
100
|
100
|
|
|
166
|
if ($name eq '-extends' or $name eq '-isa') |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
226
|
|
|
|
|
|
|
{ |
227
|
|
|
|
|
|
|
my @parents = map { |
228
|
13
|
|
|
|
|
38
|
exists $self->class_map->{$_} |
229
|
13
|
100
|
|
|
|
107
|
? $self->class_map->{$_}->() |
230
|
|
|
|
|
|
|
: $_ |
231
|
|
|
|
|
|
|
} @$val; |
232
|
13
|
|
|
|
|
68
|
"Moo"->_set_superclasses($klass, @parents); |
233
|
13
|
|
|
|
|
4499
|
"Moo"->_maybe_reset_handlemoose($klass); |
234
|
|
|
|
|
|
|
|
235
|
13
|
100
|
|
|
|
392
|
if ($self->trace) |
236
|
|
|
|
|
|
|
{ |
237
|
1
|
|
|
|
|
39
|
$self->trace_handle->printf( |
238
|
|
|
|
|
|
|
"extends qw(%s)\n", |
239
|
|
|
|
|
|
|
join(q[ ] => @parents), |
240
|
|
|
|
|
|
|
); |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
13
|
100
|
|
|
|
147
|
return map { $_->can('FIELDS') ? $_->FIELDS : () } @parents; |
|
13
|
|
|
|
|
146
|
|
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
elsif ($name eq '-with') |
246
|
|
|
|
|
|
|
{ |
247
|
2
|
|
|
|
|
15
|
require Moo::Role; |
248
|
2
|
|
|
|
|
21
|
"Moo::Role"->apply_roles_to_package($klass, @$val); |
249
|
2
|
|
|
|
|
2934
|
"Moo"->_maybe_reset_handlemoose($klass); |
250
|
|
|
|
|
|
|
|
251
|
2
|
100
|
|
|
|
59
|
if ($self->trace) |
252
|
|
|
|
|
|
|
{ |
253
|
1
|
|
|
|
|
25
|
$self->trace_handle->printf( |
254
|
|
|
|
|
|
|
"with qw(%s)\n", |
255
|
|
|
|
|
|
|
join(q[ ] => @$val), |
256
|
|
|
|
|
|
|
); |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
return |
260
|
|
|
|
|
|
|
# map { my $role = $_; grep { not ref $_ } @{ $Moo::Role::INFO{$role}{attributes} } } |
261
|
|
|
|
|
|
|
# @$val; |
262
|
2
|
|
|
|
|
35
|
} |
263
|
|
|
|
|
|
|
elsif ($name eq '-class') |
264
|
|
|
|
|
|
|
{ |
265
|
|
|
|
|
|
|
# skip; already handled by 'create_class' method (hopefully) |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
else |
268
|
|
|
|
|
|
|
{ |
269
|
1
|
|
|
|
|
198
|
confess("option '$name' unknown"); |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
4
|
|
|
|
|
29
|
return; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub process_method |
276
|
|
|
|
|
|
|
{ |
277
|
79
|
|
|
79
|
0
|
263
|
my ($self, $klass, $name, $coderef) = @_; |
278
|
79
|
|
|
|
|
342
|
__install_sub__ { |
279
|
|
|
|
|
|
|
into => $klass, |
280
|
|
|
|
|
|
|
as => $name, |
281
|
|
|
|
|
|
|
code => $coderef, |
282
|
|
|
|
|
|
|
}; |
283
|
79
|
100
|
|
|
|
1757
|
if ($self->trace) |
284
|
|
|
|
|
|
|
{ |
285
|
6
|
|
|
|
|
137
|
$self->trace_handle->printf( |
286
|
|
|
|
|
|
|
"sub %s { ... }\n", |
287
|
|
|
|
|
|
|
$name, |
288
|
|
|
|
|
|
|
); |
289
|
6
|
100
|
|
|
|
122
|
if ($self->flags->{deparse}) |
290
|
|
|
|
|
|
|
{ |
291
|
3
|
|
|
|
|
16
|
require B::Deparse; |
292
|
3
|
|
|
|
|
3835
|
my $code = "B::Deparse"->new(qw(-q -si8T))->coderef2text($coderef); |
293
|
3
|
|
|
|
|
49
|
$code =~ s/^/# /mig; |
294
|
3
|
|
|
|
|
76
|
$self->trace_handle->printf("$code\n"); |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
} |
297
|
79
|
|
|
|
|
692
|
return; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
16
|
|
|
|
|
1350
|
my $ScalarLike; |
301
|
|
|
|
|
|
|
sub process_spec |
302
|
|
|
|
|
|
|
{ |
303
|
55
|
|
|
55
|
0
|
131
|
my ($self, $klass, $name, $val) = @_; |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
my %spec = ( |
306
|
55
|
100
|
|
|
|
279
|
is => ($self->flags->{rw} ? 'rw' : 'ro'), |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
307
|
|
|
|
|
|
|
( ArrayLike->check($val) |
308
|
|
|
|
|
|
|
? @$val |
309
|
|
|
|
|
|
|
: ( HashLike->check($val) ? %$val : () ) |
310
|
|
|
|
|
|
|
), |
311
|
|
|
|
|
|
|
); |
312
|
|
|
|
|
|
|
|
313
|
55
|
100
|
|
|
|
11278
|
if ($name =~ /^(.+)\!$/) |
314
|
|
|
|
|
|
|
{ |
315
|
3
|
|
|
|
|
10
|
$name = $1; |
316
|
3
|
|
|
|
|
7
|
$spec{required} = 1; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
55
|
100
|
|
|
|
367
|
if ($name =~ /^\@(.+)/) |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
320
|
|
|
|
|
|
|
{ |
321
|
2
|
|
|
|
|
6
|
$name = $1; |
322
|
2
|
|
66
|
|
|
20
|
$spec{isa} ||= ArrayLike; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
elsif ($name =~ /^\%(.+)/) |
325
|
|
|
|
|
|
|
{ |
326
|
2
|
|
|
|
|
6
|
$name = $1; |
327
|
2
|
|
66
|
|
|
8
|
$spec{isa} ||= HashLike; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
elsif ($name =~ /^\+(.+)/) |
330
|
|
|
|
|
|
|
{ |
331
|
15
|
|
|
|
|
44
|
$name = $1; |
332
|
15
|
|
66
|
|
|
93
|
$spec{isa} ||= Num; |
333
|
15
|
100
|
100
|
10
|
|
210
|
$spec{default} ||= sub { 0 } unless $spec{required}; |
|
10
|
|
|
|
|
566
|
|
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
elsif ($name =~ /^\$(.+)/) |
336
|
|
|
|
|
|
|
{ |
337
|
19
|
|
66
|
|
|
104
|
$ScalarLike ||= (~(ArrayRef|HashRef))->create_child_type(name => 'ScalarLike'); |
338
|
19
|
|
|
|
|
4051
|
$name = $1; |
339
|
19
|
|
66
|
|
|
130
|
$spec{isa} ||= $ScalarLike; |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
55
|
|
|
|
|
249
|
return ($name, \%spec); |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
sub process_attribute |
346
|
|
|
|
|
|
|
{ |
347
|
55
|
|
|
55
|
0
|
149
|
my ($self, $klass, $name, $val) = @_; |
348
|
55
|
|
|
|
|
83
|
my $spec; |
349
|
55
|
|
|
|
|
156
|
($name, $spec) = $self->process_spec($klass, $name, $val); |
350
|
|
|
|
|
|
|
|
351
|
55
|
100
|
|
|
|
1251
|
if ($self->trace) |
352
|
|
|
|
|
|
|
{ |
353
|
3
|
|
|
|
|
677
|
require Data::Dumper; |
354
|
3
|
|
|
|
|
6907
|
my %sanespec = %$spec; |
355
|
3
|
100
|
|
|
|
12
|
if (TypeTiny->check($sanespec{isa})) { |
356
|
2
|
|
|
|
|
73
|
$sanespec{isa} = $sanespec{isa}->display_name; |
357
|
|
|
|
|
|
|
} |
358
|
3
|
|
|
|
|
45
|
my $spec_str = "Data::Dumper"->new([\%sanespec])->Terse(1)->Indent(0)->Sortkeys(1)->Dump; |
359
|
3
|
|
|
|
|
281
|
$spec_str =~ s/(^\{)|(\}$)//g; |
360
|
3
|
|
|
|
|
72
|
$self->trace_handle->printf( |
361
|
|
|
|
|
|
|
"has %s => (%s);\n", |
362
|
|
|
|
|
|
|
$name, |
363
|
|
|
|
|
|
|
$spec_str, |
364
|
|
|
|
|
|
|
); |
365
|
3
|
50
|
66
|
|
|
79
|
if ($self->flags->{deparse} and CodeRef->check($spec->{isa})) |
366
|
|
|
|
|
|
|
{ |
367
|
0
|
|
|
|
|
0
|
require B::Deparse; |
368
|
0
|
|
|
|
|
0
|
my $code = "B::Deparse"->new(qw(-q -si8T))->coderef2text($spec->{isa}); |
369
|
0
|
|
|
|
|
0
|
$code =~ s/^/# /mig; |
370
|
0
|
|
|
|
|
0
|
$self->trace_handle->printf("$code\n"); |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
"Moo" |
375
|
55
|
|
|
|
|
618
|
->_constructor_maker_for($klass) |
376
|
|
|
|
|
|
|
->register_attribute_specs($name, $spec); |
377
|
|
|
|
|
|
|
|
378
|
55
|
|
|
|
|
17590
|
"Moo" |
379
|
|
|
|
|
|
|
->_accessor_maker_for($klass) |
380
|
|
|
|
|
|
|
->generate_method($klass, $name, $spec); |
381
|
|
|
|
|
|
|
|
382
|
55
|
|
|
|
|
22937
|
"Moo" |
383
|
|
|
|
|
|
|
->_maybe_reset_handlemoose($klass); |
384
|
|
|
|
|
|
|
|
385
|
55
|
|
|
|
|
444
|
return $name; |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
# returns a list of "fields" resulting from the argument |
389
|
|
|
|
|
|
|
sub process_argument |
390
|
|
|
|
|
|
|
{ |
391
|
78
|
|
|
78
|
0
|
139
|
my $self = shift; |
392
|
78
|
|
|
|
|
170
|
my ($klass, $name, $val) = @_; |
393
|
|
|
|
|
|
|
|
394
|
78
|
100
|
|
|
|
236
|
return $self->process_method(@_) if CodeLike->check($val); |
395
|
75
|
100
|
|
|
|
9616
|
return $self->process_meta(@_) if $name =~ /^-/; |
396
|
55
|
|
|
|
|
177
|
return $self->process_attribute(@_); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub make_sub |
400
|
|
|
|
|
|
|
{ |
401
|
39
|
|
|
39
|
0
|
88
|
my ($self, $subname, $proto) = @_; |
402
|
|
|
|
|
|
|
return sub (;$) |
403
|
|
|
|
|
|
|
{ |
404
|
117
|
|
|
117
|
|
31863
|
1; # bizarre, but necessary if $] < 5.014 |
405
|
117
|
100
|
|
|
|
327
|
if (ref $proto) # inflate! |
406
|
|
|
|
|
|
|
{ |
407
|
39
|
|
|
|
|
153
|
my $opts = Exporter::Tiny::mkopt($proto); |
408
|
39
|
|
|
|
|
1140
|
my $klass = $self->create_class($opts); |
409
|
39
|
|
|
|
|
75
|
my $seen_extends; |
410
|
|
|
|
|
|
|
my @fields = _uniq map { |
411
|
39
|
100
|
|
|
|
101
|
++$seen_extends if $_->[0] eq '-extends'; |
|
78
|
|
|
|
|
238
|
|
412
|
78
|
|
|
|
|
234
|
$self->process_argument($klass, @$_); |
413
|
|
|
|
|
|
|
} @$opts; |
414
|
38
|
100
|
100
|
|
|
452
|
unshift @fields, $self->base->FIELDS |
415
|
|
|
|
|
|
|
if !$seen_extends && $self->base->can('FIELDS'); |
416
|
38
|
|
|
110
|
|
306
|
$self->process_method($klass, FIELDS => sub { @fields }); |
|
110
|
|
|
|
|
4369
|
|
417
|
38
|
50
|
|
4
|
|
318
|
$self->process_method($klass, TYPE => sub { $subname }) if defined $subname; |
|
4
|
|
|
|
|
34
|
|
418
|
38
|
|
|
|
|
131
|
$proto = $klass; |
419
|
|
|
|
|
|
|
} |
420
|
116
|
100
|
|
|
|
663
|
return $proto->new(@_) if @_; |
421
|
91
|
|
|
|
|
936
|
return $proto; |
422
|
|
|
|
|
|
|
} |
423
|
39
|
|
|
|
|
313
|
} |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
sub process |
426
|
|
|
|
|
|
|
{ |
427
|
25
|
|
|
25
|
0
|
666
|
my $self = shift; |
428
|
25
|
|
|
|
|
48
|
my $caller = shift; |
429
|
|
|
|
|
|
|
|
430
|
25
|
|
100
|
|
|
218
|
while (@_ and $_[0] =~ /^-(.+)$/) { |
431
|
2
|
|
|
|
|
20
|
$self->flags->{ lc($1) } = !!shift; |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
|
434
|
25
|
|
|
|
|
63
|
foreach my $arg (@{ Exporter::Tiny::mkopt(\@_) }) |
|
25
|
|
|
|
|
118
|
|
435
|
|
|
|
|
|
|
{ |
436
|
35
|
|
|
|
|
607
|
my ($subname, $details) = @$arg; |
437
|
35
|
100
|
|
|
|
94
|
$details = [] unless defined $details; |
438
|
|
|
|
|
|
|
|
439
|
35
|
|
|
|
|
95
|
$self->class_map->{ $subname } = $self->make_sub($subname, $details); |
440
|
|
|
|
|
|
|
__install_sub__ { |
441
|
|
|
|
|
|
|
into => $caller, |
442
|
|
|
|
|
|
|
as => $subname, |
443
|
35
|
|
|
|
|
171
|
code => $self->class_map->{ $subname }, |
444
|
|
|
|
|
|
|
}; |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
on_scope_end { |
448
|
|
|
|
|
|
|
namespace::clean->clean_subroutines( |
449
|
|
|
|
|
|
|
$caller, |
450
|
18
|
|
|
18
|
|
3189
|
keys %{ $self->class_map }, |
|
18
|
|
|
|
|
175
|
|
451
|
|
|
|
|
|
|
); |
452
|
25
|
100
|
|
|
|
2520
|
} unless $self->flags->{ retain }; |
453
|
|
|
|
|
|
|
} |
454
|
|
|
|
|
|
|
}; |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
sub import |
457
|
|
|
|
|
|
|
{ |
458
|
19
|
|
|
19
|
|
2137
|
my $caller = caller; |
459
|
19
|
|
|
|
|
44
|
my $class = shift; |
460
|
19
|
|
|
|
|
218
|
"$class\::Processor"->new->process($caller, @_); |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
|
463
|
16
|
|
|
16
|
|
136
|
no Moo; |
|
16
|
|
|
|
|
32
|
|
|
16
|
|
|
|
|
110
|
|
464
|
|
|
|
|
|
|
1; |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
__END__ |