| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Class::Accessor::PackedString; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $DATE = '2017-09-01'; # DATE |
|
4
|
|
|
|
|
|
|
our $VERSION = '0.001'; # VERSION |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
#IFUNBUILT |
|
7
|
|
|
|
|
|
|
# use strict 'subs', 'vars'; |
|
8
|
|
|
|
|
|
|
# use warnings; |
|
9
|
|
|
|
|
|
|
#END IFUNBUILT |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub import { |
|
12
|
3
|
|
|
3
|
|
675
|
my ($class0, $spec) = @_; |
|
13
|
3
|
|
|
|
|
10
|
my $caller = caller(); |
|
14
|
|
|
|
|
|
|
|
|
15
|
3
|
|
|
|
|
53
|
my $class = $caller; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#IFUNBUILT |
|
18
|
|
|
|
|
|
|
# no warnings 'redefine'; |
|
19
|
|
|
|
|
|
|
#END IFUNBUILT |
|
20
|
|
|
|
|
|
|
|
|
21
|
3
|
|
|
|
|
8
|
my $attrs = $spec->{accessors}; |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# store list of accessors in the package |
|
24
|
|
|
|
|
|
|
{ |
|
25
|
|
|
|
|
|
|
#IFUNBUILT |
|
26
|
|
|
|
|
|
|
# no warnings 'once'; |
|
27
|
|
|
|
|
|
|
#END IFUNBUILT |
|
28
|
3
|
|
|
|
|
5
|
%{"$class\::HAS_PACKED"} = %$attrs; |
|
|
3
|
|
|
|
|
11
|
|
|
|
3
|
|
|
|
|
20
|
|
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# generate accessors |
|
32
|
3
|
|
|
|
|
8
|
my %idx; # key = attribute name, value = index |
|
33
|
3
|
|
|
|
|
5
|
my $pack_template = ""; |
|
34
|
3
|
|
|
|
|
17
|
for my $attr (sort keys %$attrs) { |
|
35
|
7
|
|
|
|
|
14
|
$idx{$attr} = keys(%idx); |
|
36
|
7
|
|
|
|
|
11
|
$pack_template .= $attrs->{$attr}; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
3
|
|
|
|
|
5
|
my $num_attrs = keys %$attrs; |
|
39
|
|
|
|
|
|
|
|
|
40
|
3
|
|
|
|
|
6
|
for my $attr (keys %$attrs) { |
|
41
|
7
|
|
|
|
|
12
|
my $idx = $idx{$attr}; |
|
42
|
7
|
|
|
|
|
9
|
my $code_str = 'sub (;$) {'; |
|
43
|
7
|
|
|
|
|
13
|
$code_str .= qq( my \$self = shift;); |
|
44
|
7
|
|
|
|
|
10
|
$code_str .= qq( my \@attrs = unpack("$pack_template", \$\$self);); |
|
45
|
7
|
|
|
|
|
14
|
$code_str .= qq( if (\@_) { \$attrs[$idx] = \$_[0]; \$\$self = pack("$pack_template", \@attrs) }); |
|
46
|
7
|
|
|
|
|
11
|
$code_str .= qq( return \$attrs[$idx];); |
|
47
|
7
|
|
|
|
|
9
|
$code_str .= " }"; |
|
48
|
|
|
|
|
|
|
#print "D:accessor code for $attr: ", $code_str, "\n"; |
|
49
|
7
|
0
|
|
0
|
|
676
|
*{"$class\::$attr"} = eval $code_str; |
|
|
7
|
100
|
|
|
|
37
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
4
|
|
|
|
|
45
|
|
|
|
4
|
|
|
|
|
16
|
|
|
|
4
|
|
|
|
|
11
|
|
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
5
|
|
|
|
4
|
|
|
|
|
17
|
|
|
|
4
|
|
|
|
|
946
|
|
|
|
4
|
|
|
|
|
21
|
|
|
|
4
|
|
|
|
|
12
|
|
|
|
2
|
|
|
|
|
6
|
|
|
|
2
|
|
|
|
|
8
|
|
|
|
4
|
|
|
|
|
19
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
50
|
7
|
50
|
|
|
|
33
|
die if $@; |
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# generate constructor |
|
54
|
|
|
|
|
|
|
{ |
|
55
|
3
|
|
|
|
|
6
|
my $code_str; |
|
|
3
|
|
|
|
|
5
|
|
|
56
|
3
|
|
|
|
|
7
|
$code_str = 'sub { my ($class, %args) = @_;'; |
|
57
|
3
|
|
|
|
|
5
|
$code_str .= qq( no warnings 'uninitialized';); |
|
58
|
3
|
|
|
|
|
9
|
$code_str .= qq( my \@attrs = map { undef } 1..$num_attrs;); |
|
59
|
3
|
|
|
|
|
11
|
for my $attr (sort keys %$attrs) { |
|
60
|
7
|
|
|
|
|
14
|
my $idx = $idx{$attr}; |
|
61
|
7
|
|
|
|
|
16
|
$code_str .= qq( if (exists \$args{'$attr'}) { \$attrs[$idx] = delete \$args{'$attr'} }); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
3
|
|
|
|
|
6
|
$code_str .= ' die "Unknown $class attributes in constructor: ".join(", ", sort keys %args) if keys %args;'; |
|
64
|
3
|
|
|
|
|
7
|
$code_str .= qq( my \$self = pack('$pack_template', \@attrs); bless \\\$self, '$class';); |
|
65
|
3
|
|
|
|
|
6
|
$code_str .= ' }'; |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
#print "D:constructor code for class $class: ", $code_str, "\n"; |
|
68
|
3
|
|
100
|
|
|
12
|
my $constructor = $spec->{constructor} || "new"; |
|
69
|
3
|
50
|
|
|
|
6
|
unless (*{"$class\::$constructor"}{CODE}) { |
|
|
3
|
|
|
|
|
23
|
|
|
70
|
1
|
50
|
|
1
|
|
9
|
*{"$class\::$constructor"} = eval $code_str; |
|
|
1
|
50
|
|
1
|
|
2
|
|
|
|
1
|
50
|
|
1
|
|
125
|
|
|
|
1
|
50
|
|
1
|
|
6
|
|
|
|
1
|
50
|
|
|
|
2
|
|
|
|
1
|
50
|
|
|
|
131
|
|
|
|
1
|
50
|
|
|
|
6
|
|
|
|
1
|
50
|
|
|
|
2
|
|
|
|
1
|
50
|
|
|
|
126
|
|
|
|
3
|
50
|
|
|
|
222
|
|
|
|
3
|
|
|
|
|
14
|
|
|
|
1
|
|
|
|
|
2494
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
1122
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
9
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
2396
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
3
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
5
|
|
|
71
|
3
|
50
|
|
|
|
73
|
die if $@; |
|
72
|
|
|
|
|
|
|
}; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
1; |
|
77
|
|
|
|
|
|
|
# ABSTRACT: Generate accessors/constructor for object that use pack()-ed string as storage backend |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
__END__ |