line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
58
|
|
|
58
|
|
245
|
use strict; use warnings; |
|
58
|
|
|
58
|
|
85
|
|
|
58
|
|
|
|
|
1807
|
|
|
58
|
|
|
|
|
296
|
|
|
58
|
|
|
|
|
79
|
|
|
58
|
|
|
|
|
2190
|
|
2
|
|
|
|
|
|
|
package IO::All::Base; |
3
|
|
|
|
|
|
|
|
4
|
58
|
|
|
58
|
|
262
|
use Fcntl; |
|
58
|
|
|
|
|
79
|
|
|
58
|
|
|
|
|
18184
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
sub import { |
7
|
427
|
|
|
427
|
|
9609
|
my $class = shift; |
8
|
427
|
|
100
|
|
|
1579
|
my $flag = $_[0] || ''; |
9
|
427
|
|
|
|
|
838
|
my $package = caller; |
10
|
58
|
|
|
58
|
|
338
|
no strict 'refs'; |
|
58
|
|
|
|
|
84
|
|
|
58
|
|
|
|
|
23678
|
|
11
|
427
|
100
|
|
|
|
1350
|
if ($flag eq '-base') { |
|
|
50
|
|
|
|
|
|
12
|
340
|
|
|
|
|
386
|
push @{$package . "::ISA"}, $class; |
|
340
|
|
|
|
|
3853
|
|
13
|
2040
|
|
|
|
|
20967
|
*{$package . "::$_"} = \&$_ |
14
|
340
|
|
|
|
|
1350
|
for qw'field const option chain proxy proxy_open'; |
15
|
|
|
|
|
|
|
} |
16
|
|
|
|
|
|
|
elsif ($flag eq -mixin) { |
17
|
0
|
|
|
|
|
0
|
mixin_import(scalar(caller(0)), $class, @_); |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
else { |
20
|
87
|
|
|
|
|
168
|
my @flags = @_; |
21
|
87
|
|
|
|
|
121
|
for my $export (@{$class . '::EXPORT'}) { |
|
87
|
|
|
|
|
2357
|
|
22
|
63
|
|
|
|
|
17235
|
*{$package . "::$export"} = $export eq 'io' |
|
0
|
|
|
|
|
0
|
|
23
|
|
|
|
|
|
|
? $class->_generate_constructor(@flags) |
24
|
63
|
50
|
|
|
|
487
|
: \&{$class . "::$export"}; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub _generate_constructor { |
30
|
63
|
|
|
63
|
|
113
|
my $class = shift; |
31
|
63
|
|
|
|
|
102
|
my (@flags, %flags, $key); |
32
|
63
|
|
|
|
|
183
|
for (@_) { |
33
|
9
|
100
|
|
|
|
42
|
if (s/^-//) { |
34
|
8
|
|
|
|
|
13
|
push @flags, $_; |
35
|
8
|
|
|
|
|
13
|
$flags{$_} = 1; |
36
|
8
|
|
|
|
|
12
|
$key = $_; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
else { |
39
|
1
|
50
|
|
|
|
4
|
$flags{$key} = $_ if $key; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
} |
42
|
63
|
|
|
|
|
86
|
my $constructor; |
43
|
|
|
|
|
|
|
$constructor = sub { |
44
|
632
|
|
|
632
|
|
49707
|
my $self = $class->new(@_); |
45
|
632
|
|
|
|
|
1490
|
for (@flags) { |
46
|
12
|
|
|
|
|
75
|
$self->$_($flags{$_}); |
47
|
|
|
|
|
|
|
} |
48
|
631
|
|
|
|
|
1522
|
$self->_constructor($constructor); |
49
|
631
|
|
|
|
|
2670
|
return $self; |
50
|
|
|
|
|
|
|
} |
51
|
63
|
|
|
|
|
440
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub _init { |
54
|
772
|
|
|
772
|
|
861
|
my $self = shift; |
55
|
772
|
|
|
|
|
1691
|
$self->io_handle(undef); |
56
|
772
|
|
|
|
|
1669
|
$self->is_open(0); |
57
|
772
|
|
|
|
|
2221
|
return $self; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
#=============================================================================== |
61
|
|
|
|
|
|
|
# Closure generating functions |
62
|
|
|
|
|
|
|
#=============================================================================== |
63
|
|
|
|
|
|
|
sub option { |
64
|
560
|
|
|
560
|
0
|
795
|
my $package = caller; |
65
|
560
|
|
|
|
|
678
|
my ($field, $default) = @_; |
66
|
560
|
|
100
|
|
|
1741
|
$default ||= 0; |
67
|
560
|
|
|
|
|
1114
|
field("_$field", $default); |
68
|
58
|
|
|
58
|
|
316
|
no strict 'refs'; |
|
58
|
|
|
|
|
83
|
|
|
58
|
|
|
|
|
7194
|
|
69
|
560
|
|
|
|
|
2097
|
*{"${package}::$field"} = |
70
|
|
|
|
|
|
|
sub { |
71
|
25
|
|
|
25
|
|
15933
|
my $self = shift; |
72
|
25
|
100
|
|
|
|
275
|
*$self->{"_$field"} = @_ ? shift(@_) : 1; |
73
|
25
|
|
|
|
|
93
|
return $self; |
74
|
560
|
|
|
|
|
1552
|
}; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub chain { |
78
|
373
|
|
|
373
|
0
|
1422
|
my $package = caller; |
79
|
373
|
|
|
|
|
545
|
my ($field, $default) = @_; |
80
|
58
|
|
|
58
|
|
295
|
no strict 'refs'; |
|
58
|
|
|
|
|
92
|
|
|
58
|
|
|
|
|
6893
|
|
81
|
373
|
|
|
|
|
1367
|
*{"${package}::$field"} = |
82
|
|
|
|
|
|
|
sub { |
83
|
6228
|
|
|
6228
|
|
7629
|
my $self = shift; |
84
|
6228
|
100
|
|
|
|
9984
|
if (@_) { |
85
|
1045
|
|
|
|
|
7896
|
*$self->{$field} = shift; |
86
|
1045
|
|
|
|
|
2095
|
return $self; |
87
|
|
|
|
|
|
|
} |
88
|
5183
|
100
|
|
|
|
13482
|
return $default unless exists *$self->{$field}; |
89
|
3924
|
|
|
|
|
17903
|
return *$self->{$field}; |
90
|
373
|
|
|
|
|
1031
|
}; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub field { |
94
|
1173
|
|
|
1173
|
0
|
1741
|
my $package = caller; |
95
|
1173
|
|
|
|
|
1282
|
my ($field, $default) = @_; |
96
|
58
|
|
|
58
|
|
301
|
no strict 'refs'; |
|
58
|
|
|
|
|
84
|
|
|
58
|
|
|
|
|
9626
|
|
97
|
1173
|
50
|
|
|
|
919
|
return if defined &{"${package}::$field"}; |
|
1173
|
|
|
|
|
5207
|
|
98
|
1173
|
|
|
|
|
4608
|
*{"${package}::$field"} = |
99
|
|
|
|
|
|
|
sub { |
100
|
10229
|
|
|
10229
|
|
25420
|
my $self = shift; |
101
|
10229
|
100
|
|
|
|
30129
|
unless (exists *$self->{$field}) { |
102
|
3559
|
50
|
|
|
|
10775
|
*$self->{$field} = |
|
|
100
|
|
|
|
|
|
103
|
|
|
|
|
|
|
ref($default) eq 'ARRAY' ? [] : |
104
|
|
|
|
|
|
|
ref($default) eq 'HASH' ? {} : |
105
|
|
|
|
|
|
|
$default; |
106
|
|
|
|
|
|
|
} |
107
|
10229
|
100
|
|
|
|
42608
|
return *$self->{$field} unless @_; |
108
|
3990
|
|
|
|
|
7040
|
*$self->{$field} = shift; |
109
|
1173
|
|
|
|
|
2986
|
}; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub const { |
113
|
95
|
|
|
95
|
0
|
304
|
my $package = caller; |
114
|
95
|
|
|
|
|
220
|
my ($field, $default) = @_; |
115
|
58
|
|
|
58
|
|
303
|
no strict 'refs'; |
|
58
|
|
|
|
|
76
|
|
|
58
|
|
|
|
|
6226
|
|
116
|
95
|
50
|
|
|
|
152
|
return if defined &{"${package}::$field"}; |
|
95
|
|
|
|
|
1044
|
|
117
|
95
|
|
|
178
|
|
573
|
*{"${package}::$field"} = sub { $default }; |
|
95
|
|
|
|
|
1317
|
|
|
178
|
|
|
|
|
575
|
|
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub proxy { |
121
|
348
|
|
|
348
|
0
|
466
|
my $package = caller; |
122
|
348
|
|
|
|
|
388
|
my ($proxy) = @_; |
123
|
58
|
|
|
58
|
|
294
|
no strict 'refs'; |
|
58
|
|
|
|
|
67
|
|
|
58
|
|
|
|
|
7687
|
|
124
|
348
|
50
|
|
|
|
281
|
return if defined &{"${package}::$proxy"}; |
|
348
|
|
|
|
|
1297
|
|
125
|
348
|
|
|
|
|
1075
|
*{"${package}::$proxy"} = |
126
|
|
|
|
|
|
|
sub { |
127
|
7
|
|
|
7
|
|
8
|
my $self = shift; |
128
|
7
|
|
|
|
|
10
|
my @return = $self->io_handle->$proxy(@_); |
129
|
7
|
|
|
|
|
41
|
$self->_error_check; |
130
|
7
|
50
|
|
|
|
31
|
wantarray ? @return : $return[0]; |
131
|
348
|
|
|
|
|
968
|
}; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub proxy_open { |
135
|
356
|
|
|
356
|
0
|
457
|
my $package = caller; |
136
|
356
|
|
|
|
|
530
|
my ($proxy, @args) = @_; |
137
|
58
|
|
|
58
|
|
285
|
no strict 'refs'; |
|
58
|
|
|
|
|
82
|
|
|
58
|
|
|
|
|
12836
|
|
138
|
356
|
50
|
|
|
|
303
|
return if defined &{"${package}::$proxy"}; |
|
356
|
|
|
|
|
1309
|
|
139
|
|
|
|
|
|
|
my $method = sub { |
140
|
60
|
|
|
60
|
|
103
|
my $self = shift; |
141
|
60
|
|
|
|
|
218
|
$self->_assert_open(@args); |
142
|
60
|
|
|
|
|
149
|
my @return = $self->io_handle->$proxy(@_); |
143
|
60
|
|
|
|
|
1434
|
$self->_error_check; |
144
|
60
|
50
|
|
|
|
183
|
wantarray ? @return : $return[0]; |
145
|
356
|
|
|
|
|
1051
|
}; |
146
|
356
|
|
|
|
|
1166
|
*{"$package\::$proxy"} = |
147
|
|
|
|
|
|
|
(@args and $args[0] eq '>') ? |
148
|
|
|
|
|
|
|
sub { |
149
|
57
|
|
|
57
|
|
475
|
my $self = shift; |
150
|
57
|
|
|
|
|
165
|
$self->$method(@_); |
151
|
57
|
|
|
|
|
116
|
return $self; |
152
|
|
|
|
|
|
|
} |
153
|
356
|
100
|
100
|
|
|
1621
|
: $method; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub mixin_import { |
157
|
0
|
|
|
0
|
0
|
|
my $target_class = shift; |
158
|
0
|
0
|
|
|
|
|
$target_class = caller(0) |
159
|
|
|
|
|
|
|
if $target_class eq 'mixin'; |
160
|
0
|
0
|
|
|
|
|
my $mixin_class = shift |
161
|
|
|
|
|
|
|
or die "Nothing to mixin"; |
162
|
0
|
|
|
|
|
|
eval "require $mixin_class"; |
163
|
0
|
|
|
|
|
|
my $pseudo_class = CORE::join '-', $target_class, $mixin_class; |
164
|
0
|
|
|
|
|
|
my %methods = mixin_methods($mixin_class); |
165
|
58
|
|
|
58
|
|
312
|
no strict 'refs'; |
|
58
|
|
|
|
|
87
|
|
|
58
|
|
|
|
|
1699
|
|
166
|
58
|
|
|
58
|
|
249
|
no warnings; |
|
58
|
|
|
|
|
74
|
|
|
58
|
|
|
|
|
7743
|
|
167
|
0
|
|
|
|
|
|
@{"$pseudo_class\::ISA"} = @{"$target_class\::ISA"}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
168
|
0
|
|
|
|
|
|
@{"$target_class\::ISA"} = ($pseudo_class); |
|
0
|
|
|
|
|
|
|
169
|
0
|
|
|
|
|
|
for (keys %methods) { |
170
|
0
|
|
|
|
|
|
*{"$pseudo_class\::$_"} = $methods{$_}; |
|
0
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub mixin_methods { |
175
|
0
|
|
|
0
|
0
|
|
my $mixin_class = shift; |
176
|
58
|
|
|
58
|
|
274
|
no strict 'refs'; |
|
58
|
|
|
|
|
103
|
|
|
58
|
|
|
|
|
6716
|
|
177
|
0
|
|
|
|
|
|
my %methods = all_methods($mixin_class); |
178
|
0
|
|
|
|
|
|
map { |
179
|
0
|
|
|
|
|
|
$methods{$_} |
180
|
0
|
|
|
|
|
|
? ($_, \ &{"$methods{$_}\::$_"}) |
181
|
0
|
0
|
|
|
|
|
: ($_, \ &{"$mixin_class\::$_"}) |
182
|
|
|
|
|
|
|
} (keys %methods); |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub all_methods { |
186
|
58
|
|
|
58
|
|
307
|
no strict 'refs'; |
|
58
|
|
|
|
|
80
|
|
|
58
|
|
|
|
|
7141
|
|
187
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
188
|
0
|
|
|
|
|
|
my %methods = map { |
189
|
0
|
|
|
|
|
|
($_, $class) |
190
|
|
|
|
|
|
|
} grep { |
191
|
0
|
0
|
|
|
|
|
defined &{"$class\::$_"} and not /^_/ |
|
0
|
|
|
|
|
|
|
192
|
0
|
|
|
|
|
|
} keys %{"$class\::"}; |
193
|
0
|
|
|
|
|
|
return (%methods); |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
1; |