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