line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Attribute::Final; |
2
|
1
|
|
|
1
|
|
37057
|
use 5.006; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
42
|
|
3
|
1
|
|
|
1
|
|
4
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
69
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
88
|
|
5
|
|
|
|
|
|
|
our $VERSION = '1.3'; |
6
|
|
|
|
|
|
|
our %marked; |
7
|
|
|
|
|
|
|
my @all_packages; |
8
|
1
|
|
|
1
|
|
6
|
use B qw(svref_2object); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
114
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub fill_packages { |
11
|
1
|
|
|
1
|
|
5
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
152
|
|
12
|
179
|
|
|
179
|
0
|
259
|
my $root = shift; |
13
|
179
|
|
|
|
|
189
|
my @subs = grep s/::$//, keys %{$root."::"}; |
|
179
|
|
|
|
|
3303
|
|
14
|
179
|
|
|
|
|
462
|
push @all_packages, $root; |
15
|
179
|
|
|
|
|
458
|
for (@subs) { |
16
|
179
|
100
|
100
|
|
|
487
|
next if $root eq "main" and $_ eq "main"; # Loop |
17
|
178
|
|
|
|
|
531
|
fill_packages($root."::".$_); |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub check { |
22
|
1
|
|
|
1
|
|
4
|
no strict 'refs'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
252
|
|
23
|
2
|
100
|
|
2
|
0
|
1257
|
fill_packages("main") unless @all_packages; |
24
|
2
|
|
|
|
|
8
|
for my $derived_pack (@all_packages) { |
25
|
210
|
100
|
|
|
|
222
|
next unless @{$derived_pack."::ISA"}; |
|
210
|
|
|
|
|
2533
|
|
26
|
74
|
|
|
|
|
137
|
for my $marked_pack (keys %marked) { |
27
|
74
|
100
|
|
|
|
1079
|
next unless $derived_pack->isa($marked_pack); |
28
|
2
|
|
|
|
|
4
|
for my $meth (@{$marked{$marked_pack}}) { |
|
2
|
|
|
|
|
7
|
|
29
|
2
|
|
|
|
|
3
|
my $glob_ref = \*{$derived_pack."::".$meth}; |
|
2
|
|
|
|
|
10
|
|
30
|
2
|
100
|
|
|
|
3
|
if (*{$glob_ref}{CODE}) { |
|
2
|
|
|
|
|
12
|
|
31
|
1
|
|
|
|
|
5
|
my $name = $marked_pack."::".$meth; |
32
|
1
|
|
|
|
|
10
|
my $b = svref_2object($glob_ref); |
33
|
1
|
|
|
|
|
17
|
die "Cannot override final method $name at ". |
34
|
|
|
|
|
|
|
$b->FILE. ", line ".$b->LINE."\n"; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
1
|
|
|
1
|
|
11
|
CHECK { Attribute::Final->check() } |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
package UNIVERSAL; |
44
|
1
|
|
|
1
|
|
1853
|
use Attribute::Handlers; |
|
1
|
|
|
|
|
6843
|
|
|
1
|
|
|
|
|
7
|
|
45
|
|
|
|
|
|
|
sub final :ATTR(CODE) { |
46
|
1
|
|
|
1
|
0
|
6752
|
my ($pack, $ref) = @_; |
47
|
1
|
|
|
|
|
2
|
push @{$marked{$pack}}, *{$ref}{NAME}; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
4
|
|
48
|
1
|
|
|
1
|
|
90
|
} |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Preloaded methods go here. |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
1; |
53
|
|
|
|
|
|
|
__END__ |