line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
58
|
|
|
58
|
|
259
|
use strict; use warnings; |
|
58
|
|
|
58
|
|
75
|
|
|
58
|
|
|
|
|
1794
|
|
|
58
|
|
|
|
|
250
|
|
|
58
|
|
|
|
|
73
|
|
|
58
|
|
|
|
|
2111
|
|
2
|
|
|
|
|
|
|
package IO::All::Base; |
3
|
|
|
|
|
|
|
|
4
|
58
|
|
|
58
|
|
246
|
use Fcntl; |
|
58
|
|
|
|
|
74
|
|
|
58
|
|
|
|
|
18239
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
sub import { |
7
|
427
|
|
|
427
|
|
12372
|
my $class = shift; |
8
|
427
|
|
100
|
|
|
1565
|
my $flag = $_[0] || ''; |
9
|
427
|
|
|
|
|
762
|
my $package = caller; |
10
|
58
|
|
|
58
|
|
344
|
no strict 'refs'; |
|
58
|
|
|
|
|
89
|
|
|
58
|
|
|
|
|
24095
|
|
11
|
427
|
100
|
|
|
|
1352
|
if ($flag eq '-base') { |
|
|
50
|
|
|
|
|
|
12
|
340
|
|
|
|
|
396
|
push @{$package . "::ISA"}, $class; |
|
340
|
|
|
|
|
4035
|
|
13
|
2040
|
|
|
|
|
21829
|
*{$package . "::$_"} = \&$_ |
14
|
340
|
|
|
|
|
1454
|
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
|
|
|
|
|
167
|
my @flags = @_; |
21
|
87
|
|
|
|
|
121
|
for my $export (@{$class . '::EXPORT'}) { |
|
87
|
|
|
|
|
2316
|
|
22
|
63
|
|
|
|
|
16466
|
*{$package . "::$export"} = $export eq 'io' |
|
0
|
|
|
|
|
0
|
|
23
|
|
|
|
|
|
|
? $class->_generate_constructor(@flags) |
24
|
63
|
50
|
|
|
|
484
|
: \&{$class . "::$export"}; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub _generate_constructor { |
30
|
63
|
|
|
63
|
|
107
|
my $class = shift; |
31
|
63
|
|
|
|
|
99
|
my (@flags, %flags, $key); |
32
|
63
|
|
|
|
|
176
|
for (@_) { |
33
|
9
|
100
|
|
|
|
46
|
if (s/^-//) { |
34
|
8
|
|
|
|
|
14
|
push @flags, $_; |
35
|
8
|
|
|
|
|
15
|
$flags{$_} = 1; |
36
|
8
|
|
|
|
|
15
|
$key = $_; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
else { |
39
|
1
|
50
|
|
|
|
3
|
$flags{$key} = $_ if $key; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
} |
42
|
63
|
|
|
|
|
84
|
my $constructor; |
43
|
|
|
|
|
|
|
$constructor = sub { |
44
|
632
|
|
|
632
|
|
54239
|
my $self = $class->new(@_); |
45
|
632
|
|
|
|
|
1365
|
for (@flags) { |
46
|
12
|
|
|
|
|
79
|
$self->$_($flags{$_}); |
47
|
|
|
|
|
|
|
} |
48
|
631
|
|
|
|
|
1296
|
$self->_constructor($constructor); |
49
|
631
|
|
|
|
|
2473
|
return $self; |
50
|
|
|
|
|
|
|
} |
51
|
63
|
|
|
|
|
430
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub _init { |
54
|
772
|
|
|
772
|
|
829
|
my $self = shift; |
55
|
772
|
|
|
|
|
1483
|
$self->io_handle(undef); |
56
|
772
|
|
|
|
|
1535
|
$self->is_open(0); |
57
|
772
|
|
|
|
|
2065
|
return $self; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
#=============================================================================== |
61
|
|
|
|
|
|
|
# Closure generating functions |
62
|
|
|
|
|
|
|
#=============================================================================== |
63
|
|
|
|
|
|
|
sub option { |
64
|
560
|
|
|
560
|
0
|
778
|
my $package = caller; |
65
|
560
|
|
|
|
|
697
|
my ($field, $default) = @_; |
66
|
560
|
|
100
|
|
|
1728
|
$default ||= 0; |
67
|
560
|
|
|
|
|
1108
|
field("_$field", $default); |
68
|
58
|
|
|
58
|
|
319
|
no strict 'refs'; |
|
58
|
|
|
|
|
83
|
|
|
58
|
|
|
|
|
7043
|
|
69
|
560
|
|
|
|
|
2136
|
*{"${package}::$field"} = |
70
|
|
|
|
|
|
|
sub { |
71
|
25
|
|
|
25
|
|
16005
|
my $self = shift; |
72
|
25
|
100
|
|
|
|
209
|
*$self->{"_$field"} = @_ ? shift(@_) : 1; |
73
|
25
|
|
|
|
|
82
|
return $self; |
74
|
560
|
|
|
|
|
1493
|
}; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub chain { |
78
|
373
|
|
|
373
|
0
|
484
|
my $package = caller; |
79
|
373
|
|
|
|
|
1079
|
my ($field, $default) = @_; |
80
|
58
|
|
|
58
|
|
288
|
no strict 'refs'; |
|
58
|
|
|
|
|
72
|
|
|
58
|
|
|
|
|
7141
|
|
81
|
373
|
|
|
|
|
1403
|
*{"${package}::$field"} = |
82
|
|
|
|
|
|
|
sub { |
83
|
6228
|
|
|
6228
|
|
6509
|
my $self = shift; |
84
|
6228
|
100
|
|
|
|
8948
|
if (@_) { |
85
|
1045
|
|
|
|
|
7893
|
*$self->{$field} = shift; |
86
|
1045
|
|
|
|
|
1788
|
return $self; |
87
|
|
|
|
|
|
|
} |
88
|
5183
|
100
|
|
|
|
11624
|
return $default unless exists *$self->{$field}; |
89
|
3924
|
|
|
|
|
15472
|
return *$self->{$field}; |
90
|
373
|
|
|
|
|
1024
|
}; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub field { |
94
|
1173
|
|
|
1173
|
0
|
1421
|
my $package = caller; |
95
|
1173
|
|
|
|
|
1388
|
my ($field, $default) = @_; |
96
|
58
|
|
|
58
|
|
289
|
no strict 'refs'; |
|
58
|
|
|
|
|
80
|
|
|
58
|
|
|
|
|
9500
|
|
97
|
1173
|
50
|
|
|
|
1005
|
return if defined &{"${package}::$field"}; |
|
1173
|
|
|
|
|
5105
|
|
98
|
1173
|
|
|
|
|
4440
|
*{"${package}::$field"} = |
99
|
|
|
|
|
|
|
sub { |
100
|
10229
|
|
|
10229
|
|
12972
|
my $self = shift; |
101
|
10229
|
100
|
|
|
|
28437
|
unless (exists *$self->{$field}) { |
102
|
3559
|
50
|
|
|
|
9863
|
*$self->{$field} = |
|
|
100
|
|
|
|
|
|
103
|
|
|
|
|
|
|
ref($default) eq 'ARRAY' ? [] : |
104
|
|
|
|
|
|
|
ref($default) eq 'HASH' ? {} : |
105
|
|
|
|
|
|
|
$default; |
106
|
|
|
|
|
|
|
} |
107
|
10229
|
100
|
|
|
|
40219
|
return *$self->{$field} unless @_; |
108
|
3990
|
|
|
|
|
6264
|
*$self->{$field} = shift; |
109
|
1173
|
|
|
|
|
2974
|
}; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub const { |
113
|
95
|
|
|
95
|
0
|
317
|
my $package = caller; |
114
|
95
|
|
|
|
|
216
|
my ($field, $default) = @_; |
115
|
58
|
|
|
58
|
|
295
|
no strict 'refs'; |
|
58
|
|
|
|
|
96
|
|
|
58
|
|
|
|
|
6126
|
|
116
|
95
|
50
|
|
|
|
160
|
return if defined &{"${package}::$field"}; |
|
95
|
|
|
|
|
1003
|
|
117
|
95
|
|
|
178
|
|
552
|
*{"${package}::$field"} = sub { $default }; |
|
95
|
|
|
|
|
1521
|
|
|
178
|
|
|
|
|
621
|
|
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub proxy { |
121
|
348
|
|
|
348
|
0
|
492
|
my $package = caller; |
122
|
348
|
|
|
|
|
367
|
my ($proxy) = @_; |
123
|
58
|
|
|
58
|
|
291
|
no strict 'refs'; |
|
58
|
|
|
|
|
70
|
|
|
58
|
|
|
|
|
8152
|
|
124
|
348
|
50
|
|
|
|
274
|
return if defined &{"${package}::$proxy"}; |
|
348
|
|
|
|
|
1333
|
|
125
|
348
|
|
|
|
|
1122
|
*{"${package}::$proxy"} = |
126
|
|
|
|
|
|
|
sub { |
127
|
7
|
|
|
7
|
|
11
|
my $self = shift; |
128
|
7
|
|
|
|
|
19
|
my @return = $self->io_handle->$proxy(@_); |
129
|
7
|
|
|
|
|
66
|
$self->_error_check; |
130
|
7
|
50
|
|
|
|
51
|
wantarray ? @return : $return[0]; |
131
|
348
|
|
|
|
|
1019
|
}; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub proxy_open { |
135
|
356
|
|
|
356
|
0
|
475
|
my $package = caller; |
136
|
356
|
|
|
|
|
516
|
my ($proxy, @args) = @_; |
137
|
58
|
|
|
58
|
|
277
|
no strict 'refs'; |
|
58
|
|
|
|
|
80
|
|
|
58
|
|
|
|
|
12905
|
|
138
|
356
|
50
|
|
|
|
295
|
return if defined &{"${package}::$proxy"}; |
|
356
|
|
|
|
|
1328
|
|
139
|
|
|
|
|
|
|
my $method = sub { |
140
|
60
|
|
|
60
|
|
90
|
my $self = shift; |
141
|
60
|
|
|
|
|
234
|
$self->_assert_open(@args); |
142
|
60
|
|
|
|
|
157
|
my @return = $self->io_handle->$proxy(@_); |
143
|
60
|
|
|
|
|
1239
|
$self->_error_check; |
144
|
60
|
50
|
|
|
|
192
|
wantarray ? @return : $return[0]; |
145
|
356
|
|
|
|
|
1003
|
}; |
146
|
356
|
|
|
|
|
1131
|
*{"$package\::$proxy"} = |
147
|
|
|
|
|
|
|
(@args and $args[0] eq '>') ? |
148
|
|
|
|
|
|
|
sub { |
149
|
57
|
|
|
57
|
|
460
|
my $self = shift; |
150
|
57
|
|
|
|
|
173
|
$self->$method(@_); |
151
|
57
|
|
|
|
|
128
|
return $self; |
152
|
|
|
|
|
|
|
} |
153
|
356
|
100
|
100
|
|
|
1610
|
: $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
|
|
296
|
no strict 'refs'; |
|
58
|
|
|
|
|
92
|
|
|
58
|
|
|
|
|
1658
|
|
166
|
58
|
|
|
58
|
|
262
|
no warnings; |
|
58
|
|
|
|
|
79
|
|
|
58
|
|
|
|
|
7985
|
|
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
|
|
298
|
no strict 'refs'; |
|
58
|
|
|
|
|
92
|
|
|
58
|
|
|
|
|
6940
|
|
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
|
|
295
|
no strict 'refs'; |
|
58
|
|
|
|
|
75
|
|
|
58
|
|
|
|
|
7267
|
|
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; |