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__ |