line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
12
|
|
|
18
|
|
344964
|
use 5.008; |
|
12
|
|
|
|
|
42
|
|
|
12
|
|
|
|
|
498
|
|
2
|
12
|
|
|
12
|
|
67
|
use strict; |
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
318
|
|
3
|
12
|
|
|
12
|
|
58
|
use warnings; |
|
12
|
|
|
|
|
23
|
|
|
12
|
|
|
|
|
866
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Class::Accessor::Complex; |
6
|
|
|
|
|
|
|
our $VERSION = '1.100880'; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
# ABSTRACT: Arrays, hashes, booleans, integers, sets and more |
9
|
12
|
|
|
12
|
|
63
|
use Carp qw(carp croak cluck); |
|
12
|
|
|
|
|
19
|
|
|
12
|
|
|
|
|
1325
|
|
10
|
12
|
|
|
12
|
|
10905
|
use Data::Miscellany 'flatten'; |
|
12
|
|
|
|
|
15824
|
|
|
12
|
|
|
|
|
768
|
|
11
|
12
|
|
|
12
|
|
11622
|
use List::MoreUtils 'uniq'; |
|
12
|
|
|
|
|
19719
|
|
|
12
|
|
|
|
|
1101
|
|
12
|
12
|
|
|
12
|
|
87
|
use parent qw(Class::Accessor Class::Accessor::Installer); |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
109
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub mk_new { |
15
|
14
|
|
|
14
|
1
|
244
|
my ($self, @args) = @_; |
16
|
14
|
|
33
|
|
|
117
|
my $class = ref $self || $self; |
17
|
14
|
50
|
|
|
|
76
|
@args = ('new') unless @args; |
18
|
14
|
|
|
|
|
38
|
for my $name (@args) { |
19
|
|
|
|
|
|
|
$self->install_accessor( |
20
|
|
|
|
|
|
|
name => $name, |
21
|
|
|
|
|
|
|
code => sub { |
22
|
36
|
50
|
33
|
36
|
|
3012
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
|
|
|
|
36
|
|
|
|
23
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# don't use $class, as that's already defined above |
26
|
36
|
|
|
|
|
71
|
my $this_class = shift; |
27
|
36
|
50
|
|
|
|
139
|
my $self = ref($this_class) ? $this_class : bless {}, |
28
|
|
|
|
|
|
|
$this_class; |
29
|
0
|
|
|
|
|
0
|
my %args = |
30
|
|
|
|
|
|
|
(scalar(@_ == 1) && ref($_[0]) eq 'HASH') |
31
|
36
|
50
|
33
|
|
|
187
|
? %{ $_[0] } |
32
|
|
|
|
|
|
|
: @_; |
33
|
36
|
|
|
|
|
146
|
$self->$_($args{$_}) for keys %args; |
34
|
36
|
50
|
|
|
|
333
|
$self->init(%args) if $self->can('init'); |
35
|
36
|
|
|
|
|
178
|
$self; |
36
|
|
|
|
|
|
|
}, |
37
|
14
|
|
|
|
|
266
|
); |
38
|
14
|
|
|
|
|
673
|
$self->document_accessor( |
39
|
|
|
|
|
|
|
name => $name, |
40
|
|
|
|
|
|
|
purpose => <<'EODOC', |
41
|
|
|
|
|
|
|
Creates and returns a new object. The constructor will accept as arguments a |
42
|
|
|
|
|
|
|
list of pairs, from component name to initial value. For each pair, the named |
43
|
|
|
|
|
|
|
component is initialized by calling the method of the same name with the given |
44
|
|
|
|
|
|
|
value. If called with a single hash reference, it is dereferenced and its |
45
|
|
|
|
|
|
|
key/value pairs are set as described before. |
46
|
|
|
|
|
|
|
EODOC |
47
|
|
|
|
|
|
|
examples => [ |
48
|
|
|
|
|
|
|
"my \$obj = $class->$name;", |
49
|
|
|
|
|
|
|
"my \$obj = $class->$name(\%args);", |
50
|
|
|
|
|
|
|
], |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
} |
53
|
14
|
|
|
|
|
8674
|
$self; # for chaining |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub mk_singleton { |
57
|
1
|
|
|
1
|
1
|
20
|
my ($self, @args) = @_; |
58
|
1
|
|
33
|
|
|
9
|
my $class = ref $self || $self; |
59
|
1
|
50
|
|
|
|
6
|
@args = ('new') unless @args; |
60
|
1
|
|
|
|
|
2
|
my $singleton; |
61
|
1
|
|
|
|
|
2
|
for my $name (@args) { |
62
|
|
|
|
|
|
|
$self->install_accessor( |
63
|
|
|
|
|
|
|
name => $name, |
64
|
|
|
|
|
|
|
code => sub { |
65
|
3
|
50
|
33
|
3
|
|
16
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
66
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
67
|
3
|
100
|
|
|
|
12
|
return $singleton if defined $singleton; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# don't use $class, as that's already defined above |
70
|
1
|
|
|
|
|
3
|
my $this_class = shift; |
71
|
1
|
50
|
|
|
|
7
|
$singleton = |
72
|
|
|
|
|
|
|
ref($this_class) |
73
|
|
|
|
|
|
|
? $this_class |
74
|
|
|
|
|
|
|
: bless {}, $this_class; |
75
|
0
|
|
|
|
|
0
|
my %args = |
76
|
|
|
|
|
|
|
(scalar(@_ == 1) && ref($_[0]) eq 'HASH') |
77
|
1
|
50
|
33
|
|
|
9
|
? %{ $_[0] } |
78
|
|
|
|
|
|
|
: @_; |
79
|
1
|
|
|
|
|
8
|
$singleton->$_($args{$_}) for keys %args; |
80
|
1
|
50
|
|
|
|
12
|
$singleton->init(%args) if $singleton->can('init'); |
81
|
1
|
|
|
|
|
5
|
$singleton; |
82
|
|
|
|
|
|
|
}, |
83
|
1
|
|
|
|
|
20
|
); |
84
|
1
|
|
|
|
|
51
|
$self->document_accessor( |
85
|
|
|
|
|
|
|
name => $name, |
86
|
|
|
|
|
|
|
purpose => <<'EODOC', |
87
|
|
|
|
|
|
|
Creates and returns a new object. The object will be a singleton, so repeated |
88
|
|
|
|
|
|
|
calls to the constructor will always return the same object. The constructor |
89
|
|
|
|
|
|
|
will accept as arguments a list of pairs, from component name to initial |
90
|
|
|
|
|
|
|
value. For each pair, the named component is initialized by calling the |
91
|
|
|
|
|
|
|
method of the same name with the given value. If called with a single hash |
92
|
|
|
|
|
|
|
reference, it is dereferenced and its key/value pairs are set as described |
93
|
|
|
|
|
|
|
before. |
94
|
|
|
|
|
|
|
EODOC |
95
|
|
|
|
|
|
|
examples => [ |
96
|
|
|
|
|
|
|
"my \$obj = $class->$name;", |
97
|
|
|
|
|
|
|
"my \$obj = $class->$name(\%args);", |
98
|
|
|
|
|
|
|
], |
99
|
|
|
|
|
|
|
); |
100
|
|
|
|
|
|
|
} |
101
|
1
|
|
|
|
|
590
|
$self; # for chaining |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub mk_scalar_accessors { |
105
|
3
|
|
|
3
|
1
|
10
|
my ($self, @fields) = @_; |
106
|
3
|
|
33
|
|
|
23
|
my $class = ref $self || $self; |
107
|
3
|
|
|
|
|
8
|
for my $field (@fields) { |
108
|
|
|
|
|
|
|
$self->install_accessor( |
109
|
|
|
|
|
|
|
name => $field, |
110
|
|
|
|
|
|
|
code => sub { |
111
|
14
|
50
|
33
|
14
|
|
53
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
112
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
113
|
14
|
100
|
|
|
|
69
|
return $_[0]->{$field} if @_ == 1; |
114
|
5
|
|
|
|
|
42
|
$_[0]->{$field} = $_[1]; |
115
|
|
|
|
|
|
|
}, |
116
|
4
|
|
|
|
|
468
|
); |
117
|
4
|
|
|
|
|
156
|
$self->document_accessor( |
118
|
|
|
|
|
|
|
name => $field, |
119
|
|
|
|
|
|
|
purpose => <<'EODOC', |
120
|
|
|
|
|
|
|
A basic getter/setter method. If called without an argument, it returns the |
121
|
|
|
|
|
|
|
value. If called with a single argument, it sets the value. |
122
|
|
|
|
|
|
|
EODOC |
123
|
|
|
|
|
|
|
examples => |
124
|
|
|
|
|
|
|
[ "my \$value = \$obj->$field;", "\$obj->$field(\$value);", ], |
125
|
|
|
|
|
|
|
); |
126
|
4
|
|
|
|
|
1791
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
127
|
4
|
|
|
|
|
14
|
for my $name (@clear_methods) { |
128
|
|
|
|
|
|
|
$self->install_accessor( |
129
|
|
|
|
|
|
|
name => $name, |
130
|
|
|
|
|
|
|
code => sub { |
131
|
0
|
0
|
0
|
7
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
132
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
133
|
0
|
|
|
|
|
0
|
$_[0]->{$field} = undef; |
134
|
|
|
|
|
|
|
}, |
135
|
8
|
|
|
|
|
155
|
); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
$self->document_accessor( |
138
|
4
|
|
|
|
|
105
|
name => \@clear_methods, |
139
|
|
|
|
|
|
|
purpose => 'Clears the value.', |
140
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
141
|
|
|
|
|
|
|
belongs_to => $field, |
142
|
|
|
|
|
|
|
); |
143
|
|
|
|
|
|
|
} |
144
|
3
|
|
|
|
|
1229
|
$self; # for chaining |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub mk_class_scalar_accessors { |
148
|
1
|
|
|
1
|
1
|
4
|
my ($self, @fields) = @_; |
149
|
1
|
|
33
|
|
|
10
|
my $class = ref $self || $self; |
150
|
1
|
|
|
|
|
2
|
for my $field (@fields) { |
151
|
1
|
|
|
|
|
2
|
my $scalar; |
152
|
|
|
|
|
|
|
$self->install_accessor( |
153
|
|
|
|
|
|
|
name => $field, |
154
|
|
|
|
|
|
|
code => sub { |
155
|
5
|
50
|
33
|
5
|
|
21
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
156
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
157
|
5
|
100
|
|
|
|
24
|
return $scalar if @_ == 1; |
158
|
1
|
|
|
|
|
2
|
$scalar = $_[1]; |
159
|
|
|
|
|
|
|
}, |
160
|
1
|
|
|
|
|
9
|
); |
161
|
1
|
|
|
|
|
34
|
$self->document_accessor( |
162
|
|
|
|
|
|
|
name => $field, |
163
|
|
|
|
|
|
|
purpose => <<'EODOC', |
164
|
|
|
|
|
|
|
A basic getter/setter method. This is a class variable, so it is shared |
165
|
|
|
|
|
|
|
between all instances of this class. Changing it in one object will change it |
166
|
|
|
|
|
|
|
for all other objects as well. If called without an argument, it returns the |
167
|
|
|
|
|
|
|
value. If called with a single argument, it sets the value. |
168
|
|
|
|
|
|
|
EODOC |
169
|
|
|
|
|
|
|
examples => |
170
|
|
|
|
|
|
|
[ "my \$value = \$obj->$field;", "\$obj->$field(\$value);", ], |
171
|
|
|
|
|
|
|
); |
172
|
1
|
|
|
|
|
474
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
173
|
1
|
|
|
|
|
4
|
for my $name (@clear_methods) { |
174
|
|
|
|
|
|
|
$self->install_accessor( |
175
|
|
|
|
|
|
|
name => $name, |
176
|
|
|
|
|
|
|
code => sub { |
177
|
1
|
50
|
33
|
1
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
178
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
179
|
1
|
|
|
|
|
2
|
$scalar = undef; |
180
|
|
|
|
|
|
|
}, |
181
|
2
|
|
|
|
|
36
|
); |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
$self->document_accessor( |
184
|
1
|
|
|
|
|
27
|
name => \@clear_methods, |
185
|
|
|
|
|
|
|
purpose => <<'EODOC', |
186
|
|
|
|
|
|
|
Clears the value. Since this is a class variable, the value will be undefined |
187
|
|
|
|
|
|
|
for all instances of this class. |
188
|
|
|
|
|
|
|
EODOC |
189
|
|
|
|
|
|
|
example => "\$obj->$clear_methods[0];", |
190
|
|
|
|
|
|
|
belongs_to => $field, |
191
|
|
|
|
|
|
|
); |
192
|
|
|
|
|
|
|
} |
193
|
1
|
|
|
|
|
425
|
$self; # for chaining |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub mk_concat_accessors { |
197
|
1
|
|
|
2
|
1
|
5
|
my ($self, @args) = @_; |
198
|
1
|
|
33
|
|
|
11
|
my $class = ref $self || $self; |
199
|
1
|
|
|
|
|
2
|
for my $arg (@args) { |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
# defaults |
202
|
2
|
|
|
|
|
487
|
my $field = $arg; |
203
|
2
|
|
|
|
|
4
|
my $join = ''; |
204
|
2
|
100
|
|
|
|
6
|
if (ref $arg eq 'ARRAY') { |
205
|
1
|
|
|
|
|
4
|
($field, $join) = @$arg; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
$self->install_accessor( |
208
|
|
|
|
|
|
|
name => $field, |
209
|
|
|
|
|
|
|
code => sub { |
210
|
11
|
50
|
33
|
12
|
|
45
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
211
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
212
|
11
|
|
|
|
|
17
|
my ($self, $text) = @_; |
213
|
11
|
100
|
|
|
|
24
|
if (defined $text) { |
214
|
4
|
100
|
|
|
|
46
|
if (defined $self->{$field}) { |
215
|
2
|
|
|
|
|
9
|
$self->{$field} = $self->{$field} . $join . $text; |
216
|
|
|
|
|
|
|
} else { |
217
|
2
|
|
|
|
|
6
|
$self->{$field} = $text; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
} |
220
|
11
|
|
|
|
|
53
|
return $self->{$field}; |
221
|
|
|
|
|
|
|
}, |
222
|
2
|
|
|
|
|
17
|
); |
223
|
2
|
|
|
|
|
67
|
$self->document_accessor( |
224
|
|
|
|
|
|
|
name => $field, |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# FIXME use the current value of $join in the docs |
227
|
|
|
|
|
|
|
purpose => <<'EODOC', |
228
|
|
|
|
|
|
|
A getter/setter method. If called without an argument, it returns the |
229
|
|
|
|
|
|
|
value. If called with a single argument, it appends to the current value. |
230
|
|
|
|
|
|
|
EODOC |
231
|
|
|
|
|
|
|
examples => |
232
|
|
|
|
|
|
|
[ "my \$value = \$obj->$field;", "\$obj->$field(\$value);", ], |
233
|
|
|
|
|
|
|
); |
234
|
2
|
|
|
|
|
1016
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
235
|
2
|
|
|
|
|
7
|
for my $name (@clear_methods) { |
236
|
|
|
|
|
|
|
$self->install_accessor( |
237
|
|
|
|
|
|
|
name => $name, |
238
|
|
|
|
|
|
|
code => sub { |
239
|
2
|
50
|
33
|
2
|
|
11
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
240
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
241
|
2
|
|
|
|
|
7
|
$_[0]->{$field} = undef; |
242
|
|
|
|
|
|
|
}, |
243
|
4
|
|
|
|
|
79
|
); |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
$self->document_accessor( |
246
|
2
|
|
|
|
|
56
|
name => \@clear_methods, |
247
|
|
|
|
|
|
|
purpose => <<'EODOC', |
248
|
|
|
|
|
|
|
Clears the value. |
249
|
|
|
|
|
|
|
EODOC |
250
|
|
|
|
|
|
|
example => "\$obj->$clear_methods[0];", |
251
|
|
|
|
|
|
|
belongs_to => $field, |
252
|
|
|
|
|
|
|
); |
253
|
|
|
|
|
|
|
} |
254
|
1
|
|
|
|
|
521
|
$self; # for chaining |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
sub mk_array_accessors { |
258
|
1
|
|
|
3
|
1
|
4
|
my ($self, @fields) = @_; |
259
|
1
|
|
33
|
|
|
8
|
my $class = ref $self || $self; |
260
|
1
|
|
|
|
|
2
|
for my $field (@fields) { |
261
|
|
|
|
|
|
|
$self->install_accessor( |
262
|
|
|
|
|
|
|
name => $field, |
263
|
|
|
|
|
|
|
code => sub { |
264
|
6
|
50
|
33
|
8
|
|
1430
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
265
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
266
|
6
|
|
|
|
|
13
|
my ($self, @list) = @_; |
267
|
6
|
100
|
|
|
|
16
|
defined $self->{$field} or $self->{$field} = []; |
268
|
1
|
50
|
|
|
|
3
|
@{ $self->{$field} } = |
|
4
|
|
|
|
|
9
|
|
269
|
6
|
100
|
|
|
|
14
|
map { ref $_ eq 'ARRAY' ? @$_ : ($_) } @list |
270
|
|
|
|
|
|
|
if @list; |
271
|
6
|
100
|
|
|
|
13
|
wantarray ? @{ $self->{$field} } : $self->{$field}; |
|
5
|
|
|
|
|
30
|
|
272
|
|
|
|
|
|
|
}, |
273
|
1
|
|
|
|
|
9
|
); |
274
|
1
|
|
|
|
|
33
|
$self->document_accessor( |
275
|
|
|
|
|
|
|
name => $field, |
276
|
|
|
|
|
|
|
purpose => <<'EODOC', |
277
|
|
|
|
|
|
|
Get or set the array values. If called without arguments, it returns the |
278
|
|
|
|
|
|
|
array in list context, or a reference to the array in scalar context. If |
279
|
|
|
|
|
|
|
called with arguments, it expands array references found therein and sets the |
280
|
|
|
|
|
|
|
values. |
281
|
|
|
|
|
|
|
EODOC |
282
|
|
|
|
|
|
|
examples => [ |
283
|
|
|
|
|
|
|
"my \@values = \$obj->$field;", |
284
|
|
|
|
|
|
|
"my \$array_ref = \$obj->$field;", |
285
|
|
|
|
|
|
|
"\$obj->$field(\@values);", |
286
|
|
|
|
|
|
|
"\$obj->$field(\$array_ref);", |
287
|
|
|
|
|
|
|
], |
288
|
|
|
|
|
|
|
); |
289
|
1
|
|
|
|
|
419
|
my @push_methods = uniq "push_${field}", "${field}_push"; |
290
|
1
|
|
|
|
|
4
|
for my $name (@push_methods) { |
291
|
|
|
|
|
|
|
$self->install_accessor( |
292
|
|
|
|
|
|
|
name => $name, |
293
|
|
|
|
|
|
|
code => sub { |
294
|
1
|
50
|
33
|
3
|
|
647
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
295
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
296
|
1
|
|
|
|
|
2
|
my $self = shift; |
297
|
1
|
|
|
|
|
2
|
push @{ $self->{$field} } => @_; |
|
1
|
|
|
|
|
4
|
|
298
|
|
|
|
|
|
|
}, |
299
|
2
|
|
|
|
|
36
|
); |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
$self->document_accessor( |
302
|
1
|
|
|
|
|
26
|
name => \@push_methods, |
303
|
|
|
|
|
|
|
belongs_to => $field, |
304
|
|
|
|
|
|
|
purpose => 'Pushes elements onto the end of the array.', |
305
|
|
|
|
|
|
|
examples => ["\$obj->$push_methods[0](\@values);"], |
306
|
|
|
|
|
|
|
); |
307
|
1
|
|
|
|
|
340
|
my @pop_methods = uniq "pop_${field}", "${field}_pop"; |
308
|
1
|
|
|
|
|
4
|
for my $name (@pop_methods) { |
309
|
|
|
|
|
|
|
$self->install_accessor( |
310
|
|
|
|
|
|
|
name => $name, |
311
|
|
|
|
|
|
|
code => sub { |
312
|
1
|
50
|
33
|
4
|
|
9
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
313
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
314
|
1
|
|
|
|
|
2
|
pop @{ $_[0]->{$field} }; |
|
1
|
|
|
|
|
3
|
|
315
|
|
|
|
|
|
|
}, |
316
|
2
|
|
|
|
|
29
|
); |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
$self->document_accessor( |
319
|
1
|
|
|
|
|
25
|
name => \@pop_methods, |
320
|
|
|
|
|
|
|
purpose => <<'EODOC', |
321
|
|
|
|
|
|
|
Pops the last element off the array, returning it. |
322
|
|
|
|
|
|
|
EODOC |
323
|
|
|
|
|
|
|
examples => ["my \$value = \$obj->$pop_methods[0];"], |
324
|
|
|
|
|
|
|
belongs_to => $field, |
325
|
|
|
|
|
|
|
); |
326
|
1
|
|
|
|
|
367
|
my @unshift_methods = uniq "unshift_${field}", "${field}_unshift"; |
327
|
1
|
|
|
|
|
3
|
for my $name (@unshift_methods) { |
328
|
|
|
|
|
|
|
$self->install_accessor( |
329
|
|
|
|
|
|
|
name => $name, |
330
|
|
|
|
|
|
|
code => sub { |
331
|
0
|
0
|
0
|
2
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
332
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
333
|
0
|
|
|
|
|
0
|
my $self = shift; |
334
|
0
|
|
|
|
|
0
|
unshift @{ $self->{$field} } => @_; |
|
0
|
|
|
|
|
0
|
|
335
|
|
|
|
|
|
|
}, |
336
|
2
|
|
|
|
|
33
|
); |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
$self->document_accessor( |
339
|
1
|
|
|
|
|
24
|
name => \@unshift_methods, |
340
|
|
|
|
|
|
|
purpose => <<'EODOC', |
341
|
|
|
|
|
|
|
Unshifts elements onto the beginning of the array. |
342
|
|
|
|
|
|
|
EODOC |
343
|
|
|
|
|
|
|
examples => ["\$obj->$unshift_methods[0](\@values);"], |
344
|
|
|
|
|
|
|
belongs_to => $field, |
345
|
|
|
|
|
|
|
); |
346
|
1
|
|
|
|
|
379
|
my @shift_methods = uniq "shift_${field}", "${field}_shift"; |
347
|
1
|
|
|
|
|
3
|
for my $name (@shift_methods) { |
348
|
|
|
|
|
|
|
$self->install_accessor( |
349
|
|
|
|
|
|
|
name => $name, |
350
|
|
|
|
|
|
|
code => sub { |
351
|
1
|
50
|
33
|
2
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
352
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
353
|
1
|
|
|
|
|
1
|
shift @{ $_[0]->{$field} }; |
|
1
|
|
|
|
|
4
|
|
354
|
|
|
|
|
|
|
}, |
355
|
2
|
|
|
|
|
31
|
); |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
$self->document_accessor( |
358
|
1
|
|
|
|
|
25
|
name => \@shift_methods, |
359
|
|
|
|
|
|
|
purpose => <<'EODOC', |
360
|
|
|
|
|
|
|
Shifts the first element off the array, returning it. |
361
|
|
|
|
|
|
|
EODOC |
362
|
|
|
|
|
|
|
examples => ["my \$value = \$obj->$shift_methods[0];"], |
363
|
|
|
|
|
|
|
belongs_to => $field, |
364
|
|
|
|
|
|
|
); |
365
|
1
|
|
|
|
|
409
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
366
|
1
|
|
|
|
|
3
|
for my $name (@clear_methods) { |
367
|
|
|
|
|
|
|
$self->install_accessor( |
368
|
|
|
|
|
|
|
name => $name, |
369
|
|
|
|
|
|
|
code => sub { |
370
|
0
|
0
|
0
|
1
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
371
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
372
|
0
|
|
|
|
|
0
|
$_[0]->{$field} = []; |
373
|
|
|
|
|
|
|
}, |
374
|
2
|
|
|
|
|
37
|
); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
$self->document_accessor( |
377
|
1
|
|
|
|
|
29
|
name => \@clear_methods, |
378
|
|
|
|
|
|
|
purpose => <<'EODOC', |
379
|
|
|
|
|
|
|
Deletes all elements from the array. |
380
|
|
|
|
|
|
|
EODOC |
381
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
382
|
|
|
|
|
|
|
belongs_to => $field, |
383
|
|
|
|
|
|
|
); |
384
|
1
|
|
|
|
|
428
|
my @count_methods = uniq "count_${field}", "${field}_count"; |
385
|
1
|
|
|
|
|
3
|
for my $name (@count_methods) { |
386
|
|
|
|
|
|
|
$self->install_accessor( |
387
|
|
|
|
|
|
|
name => $name, |
388
|
|
|
|
|
|
|
code => sub { |
389
|
6
|
50
|
33
|
7
|
|
22
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
390
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
391
|
6
|
100
|
|
|
|
29
|
exists $_[0]->{$field} ? scalar @{ $_[0]->{$field} } : 0; |
|
5
|
|
|
|
|
20
|
|
392
|
|
|
|
|
|
|
}, |
393
|
2
|
|
|
|
|
31
|
); |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
$self->document_accessor( |
396
|
1
|
|
|
|
|
41
|
name => \@count_methods, |
397
|
|
|
|
|
|
|
purpose => <<'EODOC', |
398
|
|
|
|
|
|
|
Returns the number of elements in the array. |
399
|
|
|
|
|
|
|
EODOC |
400
|
|
|
|
|
|
|
examples => ["my \$count = \$obj->$count_methods[0];"], |
401
|
|
|
|
|
|
|
belongs_to => $field, |
402
|
|
|
|
|
|
|
); |
403
|
1
|
|
|
|
|
402
|
my @splice_methods = uniq "splice_${field}", "${field}_splice"; |
404
|
1
|
|
|
|
|
5
|
for my $name (@splice_methods) { |
405
|
|
|
|
|
|
|
$self->install_accessor( |
406
|
|
|
|
|
|
|
name => $name, |
407
|
|
|
|
|
|
|
code => sub { |
408
|
1
|
50
|
33
|
7
|
|
7
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
409
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
410
|
1
|
|
|
|
|
3
|
my ($self, $offset, $len, @list) = @_; |
411
|
1
|
|
|
|
|
4
|
splice(@{ $self->{$field} }, $offset, $len, @list); |
|
1
|
|
|
|
|
8
|
|
412
|
|
|
|
|
|
|
}, |
413
|
2
|
|
|
|
|
35
|
); |
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
$self->document_accessor( |
416
|
1
|
|
|
|
|
26
|
name => \@splice_methods, |
417
|
|
|
|
|
|
|
purpose => <<'EODOC', |
418
|
|
|
|
|
|
|
Takes three arguments: An offset, a length and a list. |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
Removes the elements designated by the offset and the length from the array, |
421
|
|
|
|
|
|
|
and replaces them with the elements of the list, if any. In list context, |
422
|
|
|
|
|
|
|
returns the elements removed from the array. In scalar context, returns the |
423
|
|
|
|
|
|
|
last element removed, or C if no elements are removed. The array grows |
424
|
|
|
|
|
|
|
or shrinks as necessary. If the offset is negative then it starts that far |
425
|
|
|
|
|
|
|
from the end of the array. If the length is omitted, removes everything from |
426
|
|
|
|
|
|
|
the offset onward. If the length is negative, removes the elements from the |
427
|
|
|
|
|
|
|
offset onward except for -length elements at the end of the array. If both the |
428
|
|
|
|
|
|
|
offset and the length are omitted, removes everything. If the offset is past |
429
|
|
|
|
|
|
|
the end of the array, it issues a warning, and splices at the end of the |
430
|
|
|
|
|
|
|
array. |
431
|
|
|
|
|
|
|
EODOC |
432
|
|
|
|
|
|
|
examples => [ |
433
|
|
|
|
|
|
|
"\$obj->$splice_methods[0](2, 1, \$x, \$y);", |
434
|
|
|
|
|
|
|
"\$obj->$splice_methods[0](-1);", |
435
|
|
|
|
|
|
|
"\$obj->$splice_methods[0](0, -1);", |
436
|
|
|
|
|
|
|
], |
437
|
|
|
|
|
|
|
belongs_to => $field, |
438
|
|
|
|
|
|
|
); |
439
|
1
|
|
|
|
|
365
|
my @index_methods = uniq "index_${field}", "${field}_index"; |
440
|
1
|
|
|
|
|
3
|
for my $name (@index_methods) { |
441
|
|
|
|
|
|
|
$self->install_accessor( |
442
|
|
|
|
|
|
|
name => $name, |
443
|
|
|
|
|
|
|
code => sub { |
444
|
3
|
50
|
33
|
10
|
|
366
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
445
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
446
|
3
|
|
|
|
|
192
|
my ($self, @indices) = @_; |
447
|
3
|
|
|
|
|
6
|
my @result = map { $self->{$field}[$_] } @indices; |
|
5
|
|
|
|
|
15
|
|
448
|
3
|
100
|
|
|
|
197
|
return $result[0] if @indices == 1; |
449
|
1
|
50
|
|
|
|
9
|
wantarray ? @result : \@result; |
450
|
|
|
|
|
|
|
}, |
451
|
2
|
|
|
|
|
32
|
); |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
$self->document_accessor( |
454
|
1
|
|
|
|
|
26
|
name => \@index_methods, |
455
|
|
|
|
|
|
|
purpose => <<'EODOC', |
456
|
|
|
|
|
|
|
Takes a list of indices and returns the elements indicated by those indices. |
457
|
|
|
|
|
|
|
If only one index is given, the corresponding array element is returned. If |
458
|
|
|
|
|
|
|
several indices are given, the result is returned as an array in list context |
459
|
|
|
|
|
|
|
or as an array reference in scalar context. |
460
|
|
|
|
|
|
|
EODOC |
461
|
|
|
|
|
|
|
examples => [ |
462
|
|
|
|
|
|
|
"my \$element = \$obj->$index_methods[0](3);", |
463
|
|
|
|
|
|
|
"my \@elements = \$obj->$index_methods[0](\@indices);", |
464
|
|
|
|
|
|
|
"my \$array_ref = \$obj->$index_methods[0](\@indices);", |
465
|
|
|
|
|
|
|
], |
466
|
|
|
|
|
|
|
belongs_to => $field, |
467
|
|
|
|
|
|
|
); |
468
|
1
|
|
|
|
|
832
|
my @set_methods = uniq "set_${field}", "${field}_set"; |
469
|
1
|
|
|
|
|
4
|
for my $name (@set_methods) { |
470
|
|
|
|
|
|
|
$self->install_accessor( |
471
|
|
|
|
|
|
|
name => $name, |
472
|
|
|
|
|
|
|
code => sub { |
473
|
0
|
0
|
0
|
4
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${$name}" |
|
0
|
|
|
|
|
0
|
|
474
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
475
|
0
|
|
|
|
|
0
|
my $self = shift; |
476
|
0
|
|
|
|
|
0
|
my @args = @_; |
477
|
0
|
0
|
|
|
|
0
|
croak |
478
|
|
|
|
|
|
|
"${class}::${field}_set expects an even number of fields\n" |
479
|
|
|
|
|
|
|
if @args % 2; |
480
|
0
|
|
|
|
|
0
|
while (my ($index, $value) = splice @args, 0, 2) { |
481
|
0
|
|
|
|
|
0
|
$self->{$field}->[$index] = $value; |
482
|
|
|
|
|
|
|
} |
483
|
0
|
|
|
|
|
0
|
return @_ / 2; |
484
|
|
|
|
|
|
|
}, |
485
|
2
|
|
|
|
|
45
|
); |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
$self->document_accessor( |
488
|
1
|
|
|
|
|
29
|
name => \@set_methods, |
489
|
|
|
|
|
|
|
purpose => <<'EODOC', |
490
|
|
|
|
|
|
|
Takes a list of index/value pairs and for each pair it sets the array element |
491
|
|
|
|
|
|
|
at the indicated index to the indicated value. Returns the number of elements |
492
|
|
|
|
|
|
|
that have been set. |
493
|
|
|
|
|
|
|
EODOC |
494
|
|
|
|
|
|
|
examples => ["\$obj->$set_methods[0](1 => \$x, 5 => \$y);"], |
495
|
|
|
|
|
|
|
belongs_to => $field, |
496
|
|
|
|
|
|
|
); |
497
|
|
|
|
|
|
|
} |
498
|
1
|
|
|
|
|
477
|
$self; # for chaining |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
sub mk_class_array_accessors { |
502
|
1
|
|
|
4
|
1
|
5
|
my ($self, @fields) = @_; |
503
|
1
|
|
33
|
|
|
12
|
my $class = ref $self || $self; |
504
|
1
|
|
|
|
|
3
|
for my $field (@fields) { |
505
|
1
|
|
|
|
|
3
|
my @array; |
506
|
|
|
|
|
|
|
$self->install_accessor( |
507
|
|
|
|
|
|
|
name => $field, |
508
|
|
|
|
|
|
|
code => sub { |
509
|
16
|
50
|
33
|
16
|
|
2437
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
510
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
511
|
16
|
|
|
|
|
26
|
my ($self, @list) = @_; |
512
|
16
|
50
|
|
|
|
30
|
@array = map { ref $_ eq 'ARRAY' ? @$_ : ($_) } @list |
|
4
|
100
|
|
|
|
11
|
|
513
|
|
|
|
|
|
|
if @list; |
514
|
16
|
100
|
|
|
|
92
|
wantarray ? @array : \@array; |
515
|
|
|
|
|
|
|
}, |
516
|
1
|
|
|
|
|
13
|
); |
517
|
1
|
|
|
|
|
51
|
$self->document_accessor( |
518
|
|
|
|
|
|
|
name => $field, |
519
|
|
|
|
|
|
|
purpose => <<'EODOC', |
520
|
|
|
|
|
|
|
Get or set the array values. If called without an arguments, it returns the |
521
|
|
|
|
|
|
|
array in list context, or a reference to the array in scalar context. If |
522
|
|
|
|
|
|
|
called with arguments, it expands array references found therein and sets the |
523
|
|
|
|
|
|
|
values. |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
This is a class variable, so it is shared between all instances of this class. |
526
|
|
|
|
|
|
|
Changing it in one object will change it for all other objects as well. |
527
|
|
|
|
|
|
|
EODOC |
528
|
|
|
|
|
|
|
examples => [ |
529
|
|
|
|
|
|
|
"my \@values = \$obj->$field;", |
530
|
|
|
|
|
|
|
"my \$array_ref = \$obj->$field;", |
531
|
|
|
|
|
|
|
"\$obj->$field(\@values);", |
532
|
|
|
|
|
|
|
"\$obj->$field(\$array_ref);", |
533
|
|
|
|
|
|
|
], |
534
|
|
|
|
|
|
|
); |
535
|
1
|
|
|
|
|
462
|
my @push_methods = uniq "push_${field}", "${field}_push"; |
536
|
1
|
|
|
|
|
4
|
for my $name (@push_methods) { |
537
|
|
|
|
|
|
|
$self->install_accessor( |
538
|
|
|
|
|
|
|
name => $name, |
539
|
|
|
|
|
|
|
code => sub { |
540
|
1
|
50
|
33
|
1
|
|
5
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
541
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
542
|
1
|
|
|
|
|
2
|
my $self = shift; |
543
|
1
|
|
|
|
|
3
|
push @array => @_; |
544
|
|
|
|
|
|
|
}, |
545
|
2
|
|
|
|
|
38
|
); |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
$self->document_accessor( |
548
|
1
|
|
|
|
|
28
|
name => \@push_methods, |
549
|
|
|
|
|
|
|
purpose => <<'EODOC', |
550
|
|
|
|
|
|
|
Pushes elements onto the end of the array. Since this is a class variable, the |
551
|
|
|
|
|
|
|
value will be changed for all instances of this class. |
552
|
|
|
|
|
|
|
EODOC |
553
|
|
|
|
|
|
|
examples => ["\$obj->$push_methods[0](\@values);"], |
554
|
|
|
|
|
|
|
belongs_to => $field, |
555
|
|
|
|
|
|
|
); |
556
|
1
|
|
|
|
|
429
|
my @pop_methods = uniq "pop_${field}", "${field}_pop"; |
557
|
1
|
|
|
|
|
4
|
for my $name (@pop_methods) { |
558
|
|
|
|
|
|
|
$self->install_accessor( |
559
|
|
|
|
|
|
|
name => $name, |
560
|
|
|
|
|
|
|
code => sub { |
561
|
1
|
50
|
33
|
2
|
|
7
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
562
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
563
|
1
|
|
|
|
|
4
|
pop @array; |
564
|
|
|
|
|
|
|
}, |
565
|
2
|
|
|
|
|
37
|
); |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
$self->document_accessor( |
568
|
1
|
|
|
|
|
28
|
name => \@pop_methods, |
569
|
|
|
|
|
|
|
purpose => <<'EODOC', |
570
|
|
|
|
|
|
|
Pops the last element off the array, returning it. Since this is a class |
571
|
|
|
|
|
|
|
variable, the value will be changed for all instances of this class. |
572
|
|
|
|
|
|
|
EODOC |
573
|
|
|
|
|
|
|
examples => ["my \$value = \$obj->$pop_methods[0];"], |
574
|
|
|
|
|
|
|
belongs_to => $field, |
575
|
|
|
|
|
|
|
); |
576
|
1
|
|
|
|
|
443
|
my @field_methods = uniq "unshift_${field}", "${field}_unshift"; |
577
|
1
|
|
|
|
|
5
|
for my $name (@field_methods) { |
578
|
|
|
|
|
|
|
$self->install_accessor( |
579
|
|
|
|
|
|
|
name => $name, |
580
|
|
|
|
|
|
|
code => sub { |
581
|
0
|
0
|
0
|
2
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
582
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
583
|
0
|
|
|
|
|
0
|
my $self = shift; |
584
|
0
|
|
|
|
|
0
|
unshift @array => @_; |
585
|
|
|
|
|
|
|
}, |
586
|
2
|
|
|
|
|
38
|
); |
587
|
|
|
|
|
|
|
} |
588
|
|
|
|
|
|
|
$self->document_accessor( |
589
|
1
|
|
|
|
|
32
|
name => \@field_methods, |
590
|
|
|
|
|
|
|
purpose => <<'EODOC', |
591
|
|
|
|
|
|
|
Unshifts elements onto the beginning of the array. Since this is a class |
592
|
|
|
|
|
|
|
variable, the value will be changed for all instances of this class. |
593
|
|
|
|
|
|
|
EODOC |
594
|
|
|
|
|
|
|
examples => ["\$obj->$field_methods[0](\@values);"], |
595
|
|
|
|
|
|
|
belongs_to => $field, |
596
|
|
|
|
|
|
|
); |
597
|
1
|
|
|
|
|
448
|
my @shift_methods = uniq "shift_${field}", "${field}_shift"; |
598
|
1
|
|
|
|
|
4
|
for my $name (@shift_methods) { |
599
|
|
|
|
|
|
|
$self->install_accessor( |
600
|
|
|
|
|
|
|
name => $name, |
601
|
|
|
|
|
|
|
code => sub { |
602
|
1
|
50
|
33
|
2
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
603
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
604
|
1
|
|
|
|
|
2
|
shift @array; |
605
|
|
|
|
|
|
|
}, |
606
|
2
|
|
|
|
|
38
|
); |
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
$self->document_accessor( |
609
|
1
|
|
|
|
|
30
|
name => \@shift_methods, |
610
|
|
|
|
|
|
|
purpose => <<'EODOC', |
611
|
|
|
|
|
|
|
Shifts the first element off the array, returning it. Since this is a class |
612
|
|
|
|
|
|
|
variable, the value will be changed for all instances of this class. |
613
|
|
|
|
|
|
|
EODOC |
614
|
|
|
|
|
|
|
examples => ["my \$value = \$obj->$shift_methods[0];"], |
615
|
|
|
|
|
|
|
belongs_to => $field, |
616
|
|
|
|
|
|
|
); |
617
|
1
|
|
|
|
|
530
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
618
|
1
|
|
|
|
|
4
|
for my $name (@clear_methods) { |
619
|
|
|
|
|
|
|
$self->install_accessor( |
620
|
|
|
|
|
|
|
name => $name, |
621
|
|
|
|
|
|
|
code => sub { |
622
|
0
|
0
|
0
|
1
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
623
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
624
|
0
|
|
|
|
|
0
|
@array = (); |
625
|
|
|
|
|
|
|
}, |
626
|
2
|
|
|
|
|
39
|
); |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
$self->document_accessor( |
629
|
1
|
|
|
|
|
29
|
name => \@clear_methods, |
630
|
|
|
|
|
|
|
purpose => <<'EODOC', |
631
|
|
|
|
|
|
|
Deletes all elements from the array. Since this is a class variable, the value |
632
|
|
|
|
|
|
|
will be changed for all instances of this class. |
633
|
|
|
|
|
|
|
EODOC |
634
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
635
|
|
|
|
|
|
|
belongs_to => $field, |
636
|
|
|
|
|
|
|
); |
637
|
1
|
|
|
|
|
478
|
my @count_methods = uniq "count_${field}", "${field}_count"; |
638
|
1
|
|
|
|
|
3
|
for my $name (@count_methods) { |
639
|
|
|
|
|
|
|
$self->install_accessor( |
640
|
|
|
|
|
|
|
name => $name, |
641
|
|
|
|
|
|
|
code => sub { |
642
|
6
|
50
|
33
|
7
|
|
22
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
643
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
644
|
6
|
|
|
|
|
28
|
scalar @array; |
645
|
|
|
|
|
|
|
}, |
646
|
2
|
|
|
|
|
51
|
); |
647
|
|
|
|
|
|
|
} |
648
|
|
|
|
|
|
|
$self->document_accessor( |
649
|
1
|
|
|
|
|
26
|
name => \@count_methods, |
650
|
|
|
|
|
|
|
purpose => <<'EODOC', |
651
|
|
|
|
|
|
|
Returns the number of elements in the array. Since this is a class variable, |
652
|
|
|
|
|
|
|
the value will be changed for all instances of this class. |
653
|
|
|
|
|
|
|
EODOC |
654
|
|
|
|
|
|
|
examples => ["my \$count = \$obj->$count_methods[0];"], |
655
|
|
|
|
|
|
|
belongs_to => $field, |
656
|
|
|
|
|
|
|
); |
657
|
1
|
|
|
|
|
414
|
my @splice_methods = uniq "splice_${field}", "${field}_splice"; |
658
|
1
|
|
|
|
|
4
|
for my $name (@splice_methods) { |
659
|
|
|
|
|
|
|
$self->install_accessor( |
660
|
|
|
|
|
|
|
name => $name, |
661
|
|
|
|
|
|
|
code => sub { |
662
|
1
|
50
|
33
|
7
|
|
29
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
663
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
664
|
1
|
|
|
|
|
3
|
my ($self, $offset, $len, @list) = @_; |
665
|
1
|
|
|
|
|
7
|
splice(@array, $offset, $len, @list); |
666
|
|
|
|
|
|
|
}, |
667
|
2
|
|
|
|
|
40
|
); |
668
|
|
|
|
|
|
|
} |
669
|
|
|
|
|
|
|
$self->document_accessor( |
670
|
1
|
|
|
|
|
33
|
name => \@splice_methods, |
671
|
|
|
|
|
|
|
purpose => <<'EODOC', |
672
|
|
|
|
|
|
|
Takes three arguments: An offset, a length and a list. |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
Removes the elements designated by the offset and the length from the array, |
675
|
|
|
|
|
|
|
and replaces them with the elements of the list, if any. In list context, |
676
|
|
|
|
|
|
|
returns the elements removed from the array. In scalar context, returns the |
677
|
|
|
|
|
|
|
last element removed, or C if no elements are removed. The array grows |
678
|
|
|
|
|
|
|
or shrinks as necessary. If the offset is negative then it starts that far |
679
|
|
|
|
|
|
|
from the end of the array. If the length is omitted, removes everything from |
680
|
|
|
|
|
|
|
the offset onward. If the length is negative, removes the elements from the |
681
|
|
|
|
|
|
|
offset onward except for -length elements at the end of the array. If both the |
682
|
|
|
|
|
|
|
offset and the length are omitted, removes everything. If the offset is past |
683
|
|
|
|
|
|
|
the end of the array, it issues a warning, and splices at the end of the |
684
|
|
|
|
|
|
|
array. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
Since this is a class variable, the value will be changed for all instances of |
687
|
|
|
|
|
|
|
this class. |
688
|
|
|
|
|
|
|
EODOC |
689
|
|
|
|
|
|
|
examples => [ |
690
|
|
|
|
|
|
|
"\$obj->$splice_methods[0](2, 1, \$x, \$y);", |
691
|
|
|
|
|
|
|
"\$obj->$splice_methods[0](-1);", |
692
|
|
|
|
|
|
|
"\$obj->$splice_methods[0](0, -1);", |
693
|
|
|
|
|
|
|
], |
694
|
|
|
|
|
|
|
belongs_to => $field, |
695
|
|
|
|
|
|
|
); |
696
|
1
|
|
|
|
|
476
|
my @index_methods = uniq "index_${field}", "${field}_index"; |
697
|
1
|
|
|
|
|
3
|
for my $name (@index_methods) { |
698
|
|
|
|
|
|
|
$self->install_accessor( |
699
|
|
|
|
|
|
|
name => $name, |
700
|
|
|
|
|
|
|
code => sub { |
701
|
3
|
50
|
33
|
10
|
|
19
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
702
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
703
|
3
|
|
|
|
|
8
|
my ($self, @indices) = @_; |
704
|
3
|
|
|
|
|
7
|
my @result = map { $array[$_] } @indices; |
|
5
|
|
|
|
|
15
|
|
705
|
3
|
100
|
|
|
|
20
|
return $result[0] if @indices == 1; |
706
|
1
|
50
|
|
|
|
10
|
wantarray ? @result : \@result; |
707
|
|
|
|
|
|
|
}, |
708
|
2
|
|
|
|
|
33
|
); |
709
|
|
|
|
|
|
|
} |
710
|
|
|
|
|
|
|
$self->document_accessor( |
711
|
1
|
|
|
|
|
26
|
name => \@index_methods, |
712
|
|
|
|
|
|
|
purpose => <<'EODOC', |
713
|
|
|
|
|
|
|
Takes a list of indices and returns the elements indicated by those indices. |
714
|
|
|
|
|
|
|
If only one index is given, the corresponding array element is returned. If |
715
|
|
|
|
|
|
|
several indices are given, the result is returned as an array in list context |
716
|
|
|
|
|
|
|
or as an array reference in scalar context. |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
Since this is a class variable, the value will be changed for all instances of |
719
|
|
|
|
|
|
|
this class. |
720
|
|
|
|
|
|
|
EODOC |
721
|
|
|
|
|
|
|
examples => [ |
722
|
|
|
|
|
|
|
"my \$element = \$obj->$index_methods[0](3);", |
723
|
|
|
|
|
|
|
"my \@elements = \$obj->$index_methods[0](\@indices);", |
724
|
|
|
|
|
|
|
"my \$array_ref = \$obj->$index_methods[0](\@indices);", |
725
|
|
|
|
|
|
|
], |
726
|
|
|
|
|
|
|
belongs_to => $field, |
727
|
|
|
|
|
|
|
); |
728
|
1
|
|
|
|
|
359
|
my @set_methods = uniq "set_${field}", "${field}_set"; |
729
|
1
|
|
|
|
|
3
|
for my $name (@set_methods) { |
730
|
|
|
|
|
|
|
$self->install_accessor( |
731
|
|
|
|
|
|
|
name => $name, |
732
|
|
|
|
|
|
|
code => sub { |
733
|
0
|
0
|
0
|
4
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
734
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
735
|
0
|
|
|
|
|
0
|
my $self = shift; |
736
|
0
|
|
|
|
|
0
|
my @args = @_; |
737
|
0
|
0
|
|
|
|
0
|
croak |
738
|
|
|
|
|
|
|
"${class}::${field}_set expects an even number of fields\n" |
739
|
|
|
|
|
|
|
if @args % 2; |
740
|
0
|
|
|
|
|
0
|
while (my ($index, $value) = splice @args, 0, 2) { |
741
|
0
|
|
|
|
|
0
|
$array[$index] = $value; |
742
|
|
|
|
|
|
|
} |
743
|
0
|
|
|
|
|
0
|
return @_ / 2; |
744
|
|
|
|
|
|
|
}, |
745
|
2
|
|
|
|
|
31
|
); |
746
|
|
|
|
|
|
|
} |
747
|
|
|
|
|
|
|
$self->document_accessor( |
748
|
1
|
|
|
|
|
23
|
name => \@set_methods, |
749
|
|
|
|
|
|
|
purpose => <<'EODOC', |
750
|
|
|
|
|
|
|
Takes a list of index/value pairs and for each pair it sets the array element |
751
|
|
|
|
|
|
|
at the indicated index to the indicated value. Returns the number of elements |
752
|
|
|
|
|
|
|
that have been set. Since this is a class variable, the value will be changed |
753
|
|
|
|
|
|
|
for all instances of this class. |
754
|
|
|
|
|
|
|
EODOC |
755
|
|
|
|
|
|
|
examples => ["\$obj->$set_methods[0](1 => \$x, 5 => \$y);"], |
756
|
|
|
|
|
|
|
belongs_to => $field, |
757
|
|
|
|
|
|
|
); |
758
|
|
|
|
|
|
|
} |
759
|
1
|
|
|
|
|
346
|
$self; # for chaining |
760
|
|
|
|
|
|
|
} |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
sub mk_hash_accessors { |
763
|
1
|
|
|
4
|
1
|
5
|
my ($self, @fields) = @_; |
764
|
1
|
|
33
|
|
|
11
|
my $class = ref $self || $self; |
765
|
1
|
|
|
|
|
3
|
for my $field (@fields) { |
766
|
|
|
|
|
|
|
$self->install_accessor( |
767
|
|
|
|
|
|
|
name => $field, |
768
|
|
|
|
|
|
|
code => sub { |
769
|
9
|
50
|
33
|
9
|
|
806
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
770
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
771
|
9
|
|
|
|
|
23
|
my ($self, @list) = @_; |
772
|
9
|
50
|
|
|
|
27
|
defined $self->{$field} or $self->{$field} = {}; |
773
|
9
|
100
|
|
|
|
25
|
if (scalar @list == 1) { |
774
|
3
|
|
|
|
|
8
|
my ($key) = @list; |
775
|
3
|
100
|
|
|
|
10
|
if (my $type = ref $key) { |
776
|
2
|
100
|
|
|
|
10
|
if ($type eq 'ARRAY') { |
|
|
50
|
|
|
|
|
|
777
|
1
|
|
|
|
|
2
|
return @{ $self->{$field} }{@$key}; |
|
1
|
|
|
|
|
26
|
|
778
|
|
|
|
|
|
|
} elsif ($type eq 'HASH') { |
779
|
1
|
|
|
|
|
8
|
while (my ($subkey, $value) = each %$key) { |
780
|
2
|
|
|
|
|
10
|
$self->{$field}{$subkey} = $value; |
781
|
|
|
|
|
|
|
} |
782
|
|
|
|
|
|
|
return wantarray |
783
|
1
|
50
|
|
|
|
6
|
? %{ $self->{$field} } |
|
0
|
|
|
|
|
0
|
|
784
|
|
|
|
|
|
|
: $self->{$field}; |
785
|
|
|
|
|
|
|
} else { |
786
|
0
|
|
|
|
|
0
|
cluck |
787
|
|
|
|
|
|
|
"Unrecognized ref type for hash method: $type."; |
788
|
|
|
|
|
|
|
} |
789
|
|
|
|
|
|
|
} else { |
790
|
1
|
|
|
|
|
7
|
return $self->{$field}{$key}; |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
} else { |
793
|
6
|
|
|
|
|
7
|
while (1) { |
794
|
10
|
|
|
|
|
17
|
my $key = shift @list; |
795
|
10
|
100
|
|
|
|
25
|
defined $key or last; |
796
|
4
|
|
|
|
|
8
|
my $value = shift @list; |
797
|
4
|
50
|
|
|
|
8
|
defined $value or carp "No value for key $key."; |
798
|
4
|
|
|
|
|
22
|
$self->{$field}{$key} = $value; |
799
|
|
|
|
|
|
|
} |
800
|
6
|
100
|
|
|
|
19
|
return wantarray ? %{ $self->{$field} } : $self->{$field}; |
|
4
|
|
|
|
|
38
|
|
801
|
|
|
|
|
|
|
} |
802
|
|
|
|
|
|
|
}, |
803
|
1
|
|
|
|
|
13
|
); |
804
|
1
|
|
|
|
|
43
|
$self->document_accessor( |
805
|
|
|
|
|
|
|
name => $field, |
806
|
|
|
|
|
|
|
purpose => <<'EODOC', |
807
|
|
|
|
|
|
|
Get or set the hash values. If called without arguments, it returns the hash |
808
|
|
|
|
|
|
|
in list context, or a reference to the hash in scalar context. If called |
809
|
|
|
|
|
|
|
with a list of key/value pairs, it sets each key to its corresponding value, |
810
|
|
|
|
|
|
|
then returns the hash as described before. |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
If called with exactly one key, it returns the corresponding value. |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
If called with exactly one array reference, it returns an array whose elements |
815
|
|
|
|
|
|
|
are the values corresponding to the keys in the argument array, in the same |
816
|
|
|
|
|
|
|
order. The resulting list is returned as an array in list context, or a |
817
|
|
|
|
|
|
|
reference to the array in scalar context. |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
If called with exactly one hash reference, it updates the hash with the given |
820
|
|
|
|
|
|
|
key/value pairs, then returns the hash in list context, or a reference to the |
821
|
|
|
|
|
|
|
hash in scalar context. |
822
|
|
|
|
|
|
|
EODOC |
823
|
|
|
|
|
|
|
examples => [ |
824
|
|
|
|
|
|
|
"my \%hash = \$obj->$field;", |
825
|
|
|
|
|
|
|
"my \$hash_ref = \$obj->$field;", |
826
|
|
|
|
|
|
|
"my \$value = \$obj->$field(\$key);", |
827
|
|
|
|
|
|
|
"my \@values = \$obj->$field([ qw(foo bar) ]);", |
828
|
|
|
|
|
|
|
"\$obj->$field(\%other_hash);", |
829
|
|
|
|
|
|
|
"\$obj->$field(foo => 23, bar => 42);", |
830
|
|
|
|
|
|
|
], |
831
|
|
|
|
|
|
|
); |
832
|
1
|
|
|
|
|
569
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
833
|
1
|
|
|
|
|
4
|
for my $name (@clear_methods) { |
834
|
|
|
|
|
|
|
$self->install_accessor( |
835
|
|
|
|
|
|
|
name => $name, |
836
|
|
|
|
|
|
|
code => sub { |
837
|
1
|
50
|
33
|
1
|
|
8
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
838
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
839
|
1
|
|
|
|
|
2
|
my $self = shift; |
840
|
1
|
|
|
|
|
4
|
$self->{$field} = {}; |
841
|
|
|
|
|
|
|
}, |
842
|
2
|
|
|
|
|
40
|
); |
843
|
|
|
|
|
|
|
} |
844
|
|
|
|
|
|
|
$self->document_accessor( |
845
|
1
|
|
|
|
|
30
|
name => \@clear_methods, |
846
|
|
|
|
|
|
|
purpose => <<'EODOC', |
847
|
|
|
|
|
|
|
Deletes all keys and values from the hash. |
848
|
|
|
|
|
|
|
EODOC |
849
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
850
|
|
|
|
|
|
|
belongs_to => $field, |
851
|
|
|
|
|
|
|
); |
852
|
1
|
|
|
|
|
582
|
my @keys_methods = uniq "keys_${field}", "${field}_keys"; |
853
|
1
|
|
|
|
|
4
|
for my $name (@keys_methods) { |
854
|
|
|
|
|
|
|
$self->install_accessor( |
855
|
|
|
|
|
|
|
name => $name, |
856
|
|
|
|
|
|
|
code => sub { |
857
|
3
|
50
|
33
|
4
|
|
17
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
858
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
859
|
3
|
|
|
|
|
4
|
keys %{ $_[0]->{$field} }; |
|
3
|
|
|
|
|
35
|
|
860
|
|
|
|
|
|
|
}, |
861
|
2
|
|
|
|
|
38
|
); |
862
|
|
|
|
|
|
|
} |
863
|
|
|
|
|
|
|
$self->document_accessor( |
864
|
1
|
|
|
|
|
33
|
name => \@keys_methods, |
865
|
|
|
|
|
|
|
purpose => <<'EODOC', |
866
|
|
|
|
|
|
|
Returns a list of all hash keys in no particular order. |
867
|
|
|
|
|
|
|
EODOC |
868
|
|
|
|
|
|
|
examples => ["my \@keys = \$obj->$keys_methods[0];"], |
869
|
|
|
|
|
|
|
belongs_to => $field, |
870
|
|
|
|
|
|
|
); |
871
|
1
|
|
|
|
|
549
|
my @count_methods = uniq "count_${field}", "${field}_count"; |
872
|
1
|
|
|
|
|
5
|
for my $name (@count_methods) { |
873
|
|
|
|
|
|
|
$self->install_accessor( |
874
|
|
|
|
|
|
|
name => $name, |
875
|
|
|
|
|
|
|
code => sub { |
876
|
3
|
50
|
33
|
7
|
|
15
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
877
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
878
|
3
|
|
|
|
|
4
|
scalar keys %{ $_[0]->{$field} }; |
|
3
|
|
|
|
|
23
|
|
879
|
|
|
|
|
|
|
}, |
880
|
2
|
|
|
|
|
41
|
); |
881
|
|
|
|
|
|
|
} |
882
|
|
|
|
|
|
|
$self->document_accessor( |
883
|
1
|
|
|
|
|
32
|
name => \@count_methods, |
884
|
|
|
|
|
|
|
purpose => <<'EODOC', |
885
|
|
|
|
|
|
|
Returns the number of keys in the hash. |
886
|
|
|
|
|
|
|
EODOC |
887
|
|
|
|
|
|
|
examples => ["my \$count = \$obj->$count_methods[0];"], |
888
|
|
|
|
|
|
|
belongs_to => $field, |
889
|
|
|
|
|
|
|
); |
890
|
1
|
|
|
|
|
457
|
my @values_methods = uniq "values_${field}", "${field}_values"; |
891
|
1
|
|
|
|
|
5
|
for my $name (@values_methods) { |
892
|
|
|
|
|
|
|
$self->install_accessor( |
893
|
|
|
|
|
|
|
name => $name, |
894
|
|
|
|
|
|
|
code => sub { |
895
|
1
|
50
|
33
|
7
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
896
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
897
|
1
|
|
|
|
|
2
|
values %{ $_[0]->{$field} }; |
|
1
|
|
|
|
|
8
|
|
898
|
|
|
|
|
|
|
}, |
899
|
2
|
|
|
|
|
37
|
); |
900
|
|
|
|
|
|
|
} |
901
|
|
|
|
|
|
|
$self->document_accessor( |
902
|
1
|
|
|
|
|
32
|
name => \@values_methods, |
903
|
|
|
|
|
|
|
purpose => <<'EODOC', |
904
|
|
|
|
|
|
|
Returns a list of all hash values in no particular order. |
905
|
|
|
|
|
|
|
EODOC |
906
|
|
|
|
|
|
|
examples => ["my \@values = \$obj->$values_methods[0];"], |
907
|
|
|
|
|
|
|
belongs_to => $field, |
908
|
|
|
|
|
|
|
); |
909
|
1
|
|
|
|
|
442
|
my @exists_methods = uniq "exists_${field}", "${field}_exists"; |
910
|
1
|
|
|
|
|
4
|
for my $name (@exists_methods) { |
911
|
|
|
|
|
|
|
$self->install_accessor( |
912
|
|
|
|
|
|
|
name => $name, |
913
|
|
|
|
|
|
|
code => sub { |
914
|
3
|
50
|
33
|
7
|
|
988
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
915
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
916
|
3
|
|
|
|
|
5
|
my ($self, $key) = @_; |
917
|
3
|
50
|
|
|
|
31
|
exists $self->{$field} && exists $self->{$field}{$key}; |
918
|
|
|
|
|
|
|
}, |
919
|
2
|
|
|
|
|
40
|
); |
920
|
|
|
|
|
|
|
} |
921
|
|
|
|
|
|
|
$self->document_accessor( |
922
|
1
|
|
|
|
|
30
|
name => \@exists_methods, |
923
|
|
|
|
|
|
|
purpose => <<'EODOC', |
924
|
|
|
|
|
|
|
Takes a key and returns a true value if the key exists in the hash, and a |
925
|
|
|
|
|
|
|
false value otherwise. |
926
|
|
|
|
|
|
|
EODOC |
927
|
|
|
|
|
|
|
examples => ["if (\$obj->$exists_methods[0](\$key)) { ... }"], |
928
|
|
|
|
|
|
|
belongs_to => $field, |
929
|
|
|
|
|
|
|
); |
930
|
1
|
|
|
|
|
474
|
my @delete_methods = uniq "delete_${field}", "${field}_delete"; |
931
|
1
|
|
|
|
|
3
|
for my $name (@delete_methods) { |
932
|
|
|
|
|
|
|
$self->install_accessor( |
933
|
|
|
|
|
|
|
name => $name, |
934
|
|
|
|
|
|
|
code => sub { |
935
|
1
|
50
|
33
|
5
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
936
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
937
|
1
|
|
|
|
|
4
|
my ($self, @keys) = @_; |
938
|
1
|
|
|
|
|
11
|
delete @{ $self->{$field} }{@keys}; |
|
1
|
|
|
|
|
5
|
|
939
|
|
|
|
|
|
|
}, |
940
|
2
|
|
|
|
|
39
|
); |
941
|
|
|
|
|
|
|
} |
942
|
|
|
|
|
|
|
$self->document_accessor( |
943
|
1
|
|
|
|
|
56
|
name => \@delete_methods, |
944
|
|
|
|
|
|
|
purpose => |
945
|
|
|
|
|
|
|
'Takes a list of keys and deletes those keys from the hash.', |
946
|
|
|
|
|
|
|
examples => ["\$obj->$delete_methods[0](\@keys);"], |
947
|
|
|
|
|
|
|
belongs_to => $field, |
948
|
|
|
|
|
|
|
); |
949
|
|
|
|
|
|
|
} |
950
|
1
|
|
|
|
|
433
|
$self; # for chaining |
951
|
|
|
|
|
|
|
} |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
sub mk_class_hash_accessors { |
954
|
1
|
|
|
5
|
1
|
6
|
my ($self, @fields) = @_; |
955
|
1
|
|
33
|
|
|
11
|
my $class = ref $self || $self; |
956
|
1
|
|
|
|
|
5
|
for my $field (@fields) { |
957
|
1
|
|
|
|
|
2
|
my %hash; |
958
|
|
|
|
|
|
|
$self->install_accessor( |
959
|
|
|
|
|
|
|
name => $field, |
960
|
|
|
|
|
|
|
code => sub { |
961
|
10
|
50
|
33
|
11
|
|
38
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
|
|
|
|
68
|
|
|
|
962
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
963
|
10
|
|
|
|
|
23
|
my ($self, @list) = @_; |
964
|
10
|
100
|
|
|
|
23
|
if (scalar @list == 1) { |
965
|
3
|
|
|
|
|
5
|
my ($key) = @list; |
966
|
3
|
100
|
|
|
|
14
|
return $hash{$key} unless ref $key; |
967
|
2
|
100
|
|
|
|
12
|
return @hash{@$key} if ref $key eq 'ARRAY'; |
968
|
1
|
50
|
|
|
|
4
|
if (ref($key) eq 'HASH') { |
969
|
1
|
|
|
|
|
8
|
%hash = (%hash, %$key); |
970
|
1
|
50
|
|
|
|
7
|
return wantarray ? %hash : \%hash; |
971
|
|
|
|
|
|
|
} |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
# not a scalar, array or hash... |
974
|
0
|
|
|
|
|
0
|
cluck sprintf |
975
|
|
|
|
|
|
|
'Not a recognized ref type for static hash [%s]', |
976
|
|
|
|
|
|
|
ref($key); |
977
|
|
|
|
|
|
|
} else { |
978
|
7
|
|
|
|
|
8
|
while (1) { |
979
|
11
|
|
|
|
|
16
|
my $key = shift @list; |
980
|
11
|
100
|
|
|
|
28
|
defined $key or last; |
981
|
4
|
|
|
|
|
5
|
my $value = shift @list; |
982
|
4
|
50
|
|
|
|
9
|
defined $value or carp "No value for key $key."; |
983
|
4
|
|
|
|
|
11
|
$hash{$key} = $value; |
984
|
|
|
|
|
|
|
} |
985
|
7
|
100
|
|
|
|
68
|
return wantarray ? %hash : \%hash; |
986
|
|
|
|
|
|
|
} |
987
|
|
|
|
|
|
|
}, |
988
|
1
|
|
|
|
|
11
|
); |
989
|
1
|
|
|
|
|
45
|
$self->document_accessor( |
990
|
|
|
|
|
|
|
name => $field, |
991
|
|
|
|
|
|
|
purpose => <<'EODOC', |
992
|
|
|
|
|
|
|
Get or set the hash values. If called without arguments, it returns the hash |
993
|
|
|
|
|
|
|
in list context, or a reference to the hash in scalar context. If called |
994
|
|
|
|
|
|
|
with a list of key/value pairs, it sets each key to its corresponding value, |
995
|
|
|
|
|
|
|
then returns the hash as described before. |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
If called with exactly one key, it returns the corresponding value. |
998
|
|
|
|
|
|
|
|
999
|
|
|
|
|
|
|
If called with exactly one array reference, it returns an array whose elements |
1000
|
|
|
|
|
|
|
are the values corresponding to the keys in the argument array, in the same |
1001
|
|
|
|
|
|
|
order. The resulting list is returned as an array in list context, or a |
1002
|
|
|
|
|
|
|
reference to the array in scalar context. |
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
If called with exactly one hash reference, it updates the hash with the given |
1005
|
|
|
|
|
|
|
key/value pairs, then returns the hash in list context, or a reference to the |
1006
|
|
|
|
|
|
|
hash in scalar context. |
1007
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
This is a class variable, so it is shared between all instances of this class. |
1009
|
|
|
|
|
|
|
Changing it in one object will change it for all other objects as well. |
1010
|
|
|
|
|
|
|
EODOC |
1011
|
|
|
|
|
|
|
examples => [ |
1012
|
|
|
|
|
|
|
"my \%hash = \$obj->$field;", |
1013
|
|
|
|
|
|
|
"my \$hash_ref = \$obj->$field;", |
1014
|
|
|
|
|
|
|
"my \$value = \$obj->$field(\$key);", |
1015
|
|
|
|
|
|
|
"my \@values = \$obj->$field([ qw(foo bar) ]);", |
1016
|
|
|
|
|
|
|
"\$obj->$field(\%other_hash);", |
1017
|
|
|
|
|
|
|
"\$obj->$field(foo => 23, bar => 42);", |
1018
|
|
|
|
|
|
|
], |
1019
|
|
|
|
|
|
|
); |
1020
|
1
|
|
|
|
|
554
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
1021
|
1
|
|
|
|
|
5
|
for my $name (@clear_methods) { |
1022
|
|
|
|
|
|
|
$self->install_accessor( |
1023
|
|
|
|
|
|
|
name => $name, |
1024
|
|
|
|
|
|
|
code => sub { |
1025
|
1
|
50
|
33
|
1
|
|
7
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
|
|
|
|
21
|
|
|
|
|
|
|
|
10
|
|
|
|
1026
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1027
|
1
|
|
|
|
|
5
|
%hash = (); |
1028
|
|
|
|
|
|
|
}, |
1029
|
2
|
|
|
|
|
48
|
); |
1030
|
|
|
|
|
|
|
} |
1031
|
|
|
|
|
|
|
$self->document_accessor( |
1032
|
1
|
|
|
|
|
34
|
name => \@clear_methods, |
1033
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1034
|
|
|
|
|
|
|
Deletes all keys and values from the hash. Since this is a class variable, the |
1035
|
|
|
|
|
|
|
value will be changed for all instances of this class. |
1036
|
|
|
|
|
|
|
EODOC |
1037
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
1038
|
|
|
|
|
|
|
); |
1039
|
1
|
|
|
|
|
550
|
my @keys_methods = uniq "keys_${field}", "${field}_keys"; |
1040
|
1
|
|
|
|
|
4
|
for my $name (@keys_methods) { |
1041
|
|
|
|
|
|
|
$self->install_accessor( |
1042
|
|
|
|
|
|
|
name => $name, |
1043
|
|
|
|
|
|
|
code => sub { |
1044
|
3
|
50
|
33
|
4
|
|
14
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
|
|
|
|
5
|
|
|
|
1045
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1046
|
3
|
|
|
|
|
27
|
keys %hash; |
1047
|
|
|
|
|
|
|
}, |
1048
|
2
|
|
|
|
|
40
|
); |
1049
|
|
|
|
|
|
|
} |
1050
|
|
|
|
|
|
|
$self->document_accessor( |
1051
|
1
|
|
|
|
|
32
|
name => \@keys_methods, |
1052
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1053
|
|
|
|
|
|
|
Returns a list of all hash keys in no particular order. Since this is a class |
1054
|
|
|
|
|
|
|
variable, the value will be changed for all instances of this class. |
1055
|
|
|
|
|
|
|
EODOC |
1056
|
|
|
|
|
|
|
examples => ["my \@keys = \$obj->$keys_methods[0];"], |
1057
|
|
|
|
|
|
|
belongs_to => $field, |
1058
|
|
|
|
|
|
|
); |
1059
|
1
|
|
|
|
|
585
|
my @values_methods = uniq "values_${field}", "${field}_values"; |
1060
|
1
|
|
|
|
|
5
|
for my $name (@values_methods) { |
1061
|
|
|
|
|
|
|
$self->install_accessor( |
1062
|
|
|
|
|
|
|
name => $name, |
1063
|
|
|
|
|
|
|
code => sub { |
1064
|
1
|
50
|
33
|
5
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1065
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1066
|
1
|
|
|
|
|
9
|
values %hash; |
1067
|
|
|
|
|
|
|
}, |
1068
|
2
|
|
|
|
|
45
|
); |
1069
|
|
|
|
|
|
|
} |
1070
|
|
|
|
|
|
|
$self->document_accessor( |
1071
|
1
|
|
|
|
|
32
|
name => \@values_methods, |
1072
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1073
|
|
|
|
|
|
|
Returns a list of all hash values in no particular order. Since this is a |
1074
|
|
|
|
|
|
|
class variable, the value will be changed for all instances of this class. |
1075
|
|
|
|
|
|
|
EODOC |
1076
|
|
|
|
|
|
|
examples => ["my \@values = \$obj->$values_methods[0];"], |
1077
|
|
|
|
|
|
|
belongs_to => $field, |
1078
|
|
|
|
|
|
|
); |
1079
|
1
|
|
|
|
|
527
|
my @exists_methods = uniq "exists_${field}", "${field}_exists"; |
1080
|
1
|
|
|
|
|
4
|
for my $name (@exists_methods) { |
1081
|
|
|
|
|
|
|
$self->install_accessor( |
1082
|
|
|
|
|
|
|
name => $name, |
1083
|
|
|
|
|
|
|
code => sub { |
1084
|
3
|
50
|
33
|
7
|
|
11
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1085
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1086
|
3
|
|
|
|
|
18
|
exists $hash{ $_[1] }; |
1087
|
|
|
|
|
|
|
}, |
1088
|
2
|
|
|
|
|
39
|
); |
1089
|
|
|
|
|
|
|
} |
1090
|
|
|
|
|
|
|
$self->document_accessor( |
1091
|
1
|
|
|
|
|
35
|
name => \@exists_methods, |
1092
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1093
|
|
|
|
|
|
|
Takes a key and returns a true value if the key exists in the hash, and a |
1094
|
|
|
|
|
|
|
false value otherwise. Since this is a class variable, the value will be |
1095
|
|
|
|
|
|
|
changed for all instances of this class. |
1096
|
|
|
|
|
|
|
EODOC |
1097
|
|
|
|
|
|
|
examples => ["if (\$obj->$exists_methods[0](\$key)) { ... }"], |
1098
|
|
|
|
|
|
|
belongs_to => $field, |
1099
|
|
|
|
|
|
|
); |
1100
|
1
|
|
|
|
|
688
|
my @delete_methods = uniq "delete_${field}", "${field}_delete"; |
1101
|
1
|
|
|
|
|
4
|
for my $name (@delete_methods) { |
1102
|
|
|
|
|
|
|
$self->install_accessor( |
1103
|
|
|
|
|
|
|
name => $name, |
1104
|
|
|
|
|
|
|
code => sub { |
1105
|
1
|
50
|
33
|
5
|
|
10
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1106
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1107
|
1
|
|
|
|
|
4
|
my ($self, @keys) = @_; |
1108
|
1
|
|
|
|
|
5
|
delete @hash{@keys}; |
1109
|
|
|
|
|
|
|
}, |
1110
|
2
|
|
|
|
|
42
|
); |
1111
|
|
|
|
|
|
|
} |
1112
|
|
|
|
|
|
|
$self->document_accessor( |
1113
|
1
|
|
|
|
|
31
|
name => \@delete_methods, |
1114
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1115
|
|
|
|
|
|
|
Takes a list of keys and deletes those keys from the hash. Since this is a |
1116
|
|
|
|
|
|
|
class variable, the value will be changed for all instances of this class. |
1117
|
|
|
|
|
|
|
EODOC |
1118
|
|
|
|
|
|
|
examples => ["\$obj->$delete_methods[0](\@keys);"], |
1119
|
|
|
|
|
|
|
belongs_to => $field, |
1120
|
|
|
|
|
|
|
); |
1121
|
|
|
|
|
|
|
} |
1122
|
1
|
|
|
|
|
482
|
$self; # for chaining |
1123
|
|
|
|
|
|
|
} |
1124
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
sub mk_abstract_accessors { |
1126
|
1
|
|
|
5
|
1
|
3
|
my ($self, @fields) = @_; |
1127
|
1
|
|
33
|
|
|
11
|
my $class = ref $self || $self; |
1128
|
1
|
|
|
|
|
3
|
for my $field (@fields) { |
1129
|
|
|
|
|
|
|
$self->install_accessor( |
1130
|
|
|
|
|
|
|
name => $field, |
1131
|
|
|
|
|
|
|
code => sub { |
1132
|
1
|
50
|
33
|
2
|
|
8
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
1133
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1134
|
1
|
|
|
|
|
3
|
my $method = "${class}::${field}"; |
1135
|
1
|
|
|
|
|
90
|
eval "require Error::Hierarchy::Internal::AbstractMethod"; |
1136
|
1
|
50
|
|
|
|
7
|
if ($@) { |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
# Error::Hierarchy not installed? |
1139
|
1
|
|
|
|
|
9
|
die sprintf "called abstract method [%s]", $method; |
1140
|
|
|
|
|
|
|
} else { |
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
# need to pass method because caller() still doesn't see the |
1143
|
|
|
|
|
|
|
# anonymously named sub's name |
1144
|
0
|
|
|
|
|
0
|
throw Error::Hierarchy::Internal::AbstractMethod( |
1145
|
|
|
|
|
|
|
method => $method,); |
1146
|
|
|
|
|
|
|
} |
1147
|
|
|
|
|
|
|
} |
1148
|
1
|
|
|
|
|
76
|
); |
1149
|
|
|
|
|
|
|
} |
1150
|
1
|
|
|
|
|
31
|
$self; # for chaining |
1151
|
|
|
|
|
|
|
} |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
sub mk_boolean_accessors { |
1154
|
0
|
|
|
0
|
1
|
0
|
my ($self, @fields) = @_; |
1155
|
0
|
|
0
|
|
|
0
|
my $class = ref $self || $self; |
1156
|
0
|
|
|
|
|
0
|
for my $field (@fields) { |
1157
|
|
|
|
|
|
|
$self->install_accessor( |
1158
|
|
|
|
|
|
|
name => $field, |
1159
|
|
|
|
|
|
|
code => sub { |
1160
|
0
|
0
|
0
|
0
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
1161
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1162
|
0
|
0
|
|
|
|
0
|
return $_[0]->{$field} if @_ == 1; |
1163
|
0
|
0
|
|
|
|
0
|
$_[0]->{$field} = $_[1] ? 1 : 0; # normalize |
1164
|
|
|
|
|
|
|
}, |
1165
|
0
|
|
|
|
|
0
|
); |
1166
|
0
|
|
|
|
|
0
|
$self->document_accessor( |
1167
|
|
|
|
|
|
|
name => $field, |
1168
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1169
|
|
|
|
|
|
|
If called without an argument, returns the boolean value (0 or 1). If called |
1170
|
|
|
|
|
|
|
with an argument, it normalizes it to the boolean value. That is, the values |
1171
|
|
|
|
|
|
|
0, undef and the empty string become 0; everything else becomes 1. |
1172
|
|
|
|
|
|
|
EODOC |
1173
|
|
|
|
|
|
|
examples => |
1174
|
|
|
|
|
|
|
[ "\$obj->$field(\$value);", "my \$value = \$obj->$field;", ], |
1175
|
|
|
|
|
|
|
); |
1176
|
0
|
|
|
|
|
0
|
my @set_methods = uniq "set_${field}", "${field}_set"; |
1177
|
0
|
|
|
|
|
0
|
for my $name (@set_methods) { |
1178
|
|
|
|
|
|
|
$self->install_accessor( |
1179
|
|
|
|
|
|
|
name => $name, |
1180
|
|
|
|
|
|
|
code => sub { |
1181
|
0
|
0
|
0
|
0
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1182
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1183
|
0
|
|
|
|
|
0
|
$_[0]->{$field} = 1; |
1184
|
|
|
|
|
|
|
}, |
1185
|
0
|
|
|
|
|
0
|
); |
1186
|
|
|
|
|
|
|
} |
1187
|
|
|
|
|
|
|
$self->document_accessor( |
1188
|
0
|
|
|
|
|
0
|
name => \@set_methods, |
1189
|
|
|
|
|
|
|
purpose => 'Sets the boolean value to 1.', |
1190
|
|
|
|
|
|
|
examples => ["\$obj->$set_methods[0];"], |
1191
|
|
|
|
|
|
|
belongs_to => $field, |
1192
|
|
|
|
|
|
|
); |
1193
|
0
|
|
|
|
|
0
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
1194
|
0
|
|
|
|
|
0
|
for my $name (@clear_methods) { |
1195
|
|
|
|
|
|
|
$self->install_accessor( |
1196
|
|
|
|
|
|
|
name => $name, |
1197
|
|
|
|
|
|
|
code => sub { |
1198
|
0
|
0
|
0
|
0
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1199
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1200
|
0
|
|
|
|
|
0
|
$_[0]->{$field} = 0; |
1201
|
|
|
|
|
|
|
}, |
1202
|
0
|
|
|
|
|
0
|
); |
1203
|
|
|
|
|
|
|
} |
1204
|
|
|
|
|
|
|
$self->document_accessor( |
1205
|
0
|
|
|
|
|
0
|
name => \@clear_methods, |
1206
|
|
|
|
|
|
|
purpose => 'Clears the boolean value by setting it to 0.', |
1207
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
1208
|
|
|
|
|
|
|
belongs_to => $field, |
1209
|
|
|
|
|
|
|
); |
1210
|
|
|
|
|
|
|
} |
1211
|
0
|
|
|
|
|
0
|
$self; # for chaining |
1212
|
|
|
|
|
|
|
} |
1213
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
sub mk_integer_accessors { |
1215
|
1
|
|
|
1
|
1
|
4
|
my ($self, @fields) = @_; |
1216
|
1
|
|
33
|
|
|
9
|
my $class = ref $self || $self; |
1217
|
1
|
|
|
|
|
3
|
for my $field (@fields) { |
1218
|
|
|
|
|
|
|
$self->install_accessor( |
1219
|
|
|
|
|
|
|
name => $field, |
1220
|
|
|
|
|
|
|
code => sub { |
1221
|
9
|
50
|
33
|
9
|
|
28
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
|
|
|
|
9
|
|
|
|
|
|
|
|
9
|
|
|
|
1222
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1223
|
9
|
|
|
|
|
33
|
my $self = shift; |
1224
|
9
|
100
|
100
|
|
|
71
|
return $self->{$field} || 0 unless @_; |
1225
|
2
|
|
|
|
|
8
|
$self->{$field} = shift; |
1226
|
|
|
|
|
|
|
}, |
1227
|
2
|
|
|
|
|
458
|
); |
1228
|
2
|
|
|
|
|
65
|
$self->document_accessor( |
1229
|
|
|
|
|
|
|
name => $field, |
1230
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1231
|
|
|
|
|
|
|
A basic getter/setter method. If called without an argument, it returns the |
1232
|
|
|
|
|
|
|
value, or 0 if there is no previous value. If called with a single argument, |
1233
|
|
|
|
|
|
|
it sets the value. |
1234
|
|
|
|
|
|
|
EODOC |
1235
|
|
|
|
|
|
|
examples => |
1236
|
|
|
|
|
|
|
[ "\$obj->$field(\$value);", "my \$value = \$obj->$field;", ], |
1237
|
|
|
|
|
|
|
); |
1238
|
2
|
|
|
|
|
989
|
my @reset_methods = uniq "reset_${field}", "${field}_reset"; |
1239
|
2
|
|
|
|
|
6
|
for my $name (@reset_methods) { |
1240
|
|
|
|
|
|
|
$self->install_accessor( |
1241
|
|
|
|
|
|
|
name => $name, |
1242
|
|
|
|
|
|
|
code => sub { |
1243
|
2
|
50
|
33
|
2
|
|
9
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
1244
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1245
|
2
|
|
|
|
|
6
|
$_[0]->{$field} = 0; |
1246
|
|
|
|
|
|
|
}, |
1247
|
3
|
|
|
|
|
45
|
); |
1248
|
|
|
|
|
|
|
} |
1249
|
|
|
|
|
|
|
$self->document_accessor( |
1250
|
2
|
|
|
|
|
61
|
name => \@reset_methods, |
1251
|
|
|
|
|
|
|
purpose => 'Resets the value to 0.', |
1252
|
|
|
|
|
|
|
examples => ["\$obj->$reset_methods[0];"], |
1253
|
|
|
|
|
|
|
belongs_to => $field, |
1254
|
|
|
|
|
|
|
); |
1255
|
2
|
|
|
|
|
949
|
my @inc_methods = uniq "inc_${field}", "${field}_inc"; |
1256
|
2
|
|
|
|
|
6
|
for my $name (@inc_methods) { |
1257
|
|
|
|
|
|
|
$self->install_accessor( |
1258
|
|
|
|
|
|
|
name => $name, |
1259
|
|
|
|
|
|
|
code => sub { |
1260
|
2
|
50
|
33
|
2
|
|
10
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
1261
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1262
|
2
|
|
|
|
|
6
|
$_[0]->{$field}++; |
1263
|
|
|
|
|
|
|
}, |
1264
|
4
|
|
|
|
|
73
|
); |
1265
|
|
|
|
|
|
|
} |
1266
|
|
|
|
|
|
|
$self->document_accessor( |
1267
|
2
|
|
|
|
|
56
|
name => \@inc_methods, |
1268
|
|
|
|
|
|
|
purpose => 'Increases the value by 1.', |
1269
|
|
|
|
|
|
|
examples => ["\$obj->$inc_methods[0];"], |
1270
|
|
|
|
|
|
|
belongs_to => $field, |
1271
|
|
|
|
|
|
|
); |
1272
|
2
|
|
|
|
|
985
|
my @dec_methods = uniq "dec_${field}", "${field}_dec"; |
1273
|
2
|
|
|
|
|
7
|
for my $name (@dec_methods) { |
1274
|
|
|
|
|
|
|
$self->install_accessor( |
1275
|
|
|
|
|
|
|
name => $name, |
1276
|
|
|
|
|
|
|
code => sub { |
1277
|
2
|
50
|
33
|
2
|
|
10
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
|
2
|
|
|
|
1278
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1279
|
2
|
|
|
|
|
6
|
$_[0]->{$field}--; |
1280
|
|
|
|
|
|
|
}, |
1281
|
4
|
|
|
|
|
84
|
); |
1282
|
|
|
|
|
|
|
} |
1283
|
|
|
|
|
|
|
$self->document_accessor( |
1284
|
2
|
|
|
|
|
56
|
name => \@dec_methods, |
1285
|
|
|
|
|
|
|
purpose => 'Decreases the value by 1.', |
1286
|
|
|
|
|
|
|
examples => ["\$obj->$dec_methods[0];"], |
1287
|
|
|
|
|
|
|
belongs_to => $field, |
1288
|
|
|
|
|
|
|
); |
1289
|
|
|
|
|
|
|
} |
1290
|
1
|
|
|
|
|
461
|
$self; # for chaining |
1291
|
|
|
|
|
|
|
} |
1292
|
|
|
|
|
|
|
|
1293
|
|
|
|
|
|
|
sub mk_set_accessors { |
1294
|
1
|
|
|
1
|
1
|
4
|
my ($self, @fields) = @_; |
1295
|
1
|
|
33
|
|
|
9
|
my $class = ref $self || $self; |
1296
|
1
|
|
|
|
|
4
|
for my $field (@fields) { |
1297
|
1
|
|
|
|
|
3
|
my $insert_method = "${field}_insert"; |
1298
|
1
|
|
|
|
|
3
|
my $elements_method = "${field}_elements"; |
1299
|
|
|
|
|
|
|
$self->install_accessor( |
1300
|
|
|
|
|
|
|
name => $field, |
1301
|
|
|
|
|
|
|
code => sub { |
1302
|
2
|
50
|
33
|
2
|
|
10
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
1303
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1304
|
2
|
|
|
|
|
4
|
my $self = shift; |
1305
|
2
|
100
|
|
|
|
6
|
if (@_) { |
1306
|
1
|
|
|
|
|
4
|
$self->$insert_method(@_); |
1307
|
|
|
|
|
|
|
} else { |
1308
|
1
|
|
|
|
|
4
|
$self->$elements_method; |
1309
|
|
|
|
|
|
|
} |
1310
|
|
|
|
|
|
|
}, |
1311
|
1
|
|
|
|
|
10
|
); |
1312
|
1
|
|
|
|
|
35
|
$self->document_accessor( |
1313
|
|
|
|
|
|
|
name => $field, |
1314
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1315
|
|
|
|
|
|
|
A set is like an array except that each element can occur only one. It is, |
1316
|
|
|
|
|
|
|
however, not ordered. If called with a list of arguments, it adds those |
1317
|
|
|
|
|
|
|
elements to the set. If the first argument is an array reference, the values |
1318
|
|
|
|
|
|
|
contained therein are added to the set. If called without arguments, it |
1319
|
|
|
|
|
|
|
returns the elements of the set. |
1320
|
|
|
|
|
|
|
EODOC |
1321
|
|
|
|
|
|
|
examples => [ |
1322
|
|
|
|
|
|
|
"my \@elements = \$obj->$field;", |
1323
|
|
|
|
|
|
|
"\$obj->$field(\@elements);", |
1324
|
|
|
|
|
|
|
], |
1325
|
|
|
|
|
|
|
); |
1326
|
1
|
|
|
|
|
658
|
my @insert_methods = uniq "insert_${field}", $insert_method; |
1327
|
1
|
|
|
|
|
5
|
for my $name (@insert_methods) { |
1328
|
|
|
|
|
|
|
$self->install_accessor( |
1329
|
|
|
|
|
|
|
name => $name, |
1330
|
|
|
|
|
|
|
code => sub { |
1331
|
2
|
50
|
33
|
2
|
|
14
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1332
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1333
|
2
|
|
|
|
|
4
|
my $self = shift; |
1334
|
2
|
|
|
|
|
10
|
$self->{$field}{$_}++ for flatten(@_); |
1335
|
|
|
|
|
|
|
}, |
1336
|
2
|
|
|
|
|
43
|
); |
1337
|
|
|
|
|
|
|
} |
1338
|
|
|
|
|
|
|
$self->document_accessor( |
1339
|
1
|
|
|
|
|
33
|
name => \@insert_methods, |
1340
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1341
|
|
|
|
|
|
|
If called with a list of arguments, it adds those elements to the set. If the |
1342
|
|
|
|
|
|
|
first argument is an array reference, the values contained therein are added |
1343
|
|
|
|
|
|
|
to the set. |
1344
|
|
|
|
|
|
|
EODOC |
1345
|
|
|
|
|
|
|
examples => ["\$obj->$insert_methods[0](\@elements);"], |
1346
|
|
|
|
|
|
|
belongs_to => $field, |
1347
|
|
|
|
|
|
|
); |
1348
|
1
|
|
|
|
|
504
|
my @elements_methods = uniq "elements_${field}", $elements_method; |
1349
|
1
|
|
|
|
|
5
|
for my $name (@elements_methods) { |
1350
|
|
|
|
|
|
|
$self->install_accessor( |
1351
|
|
|
|
|
|
|
name => $name, |
1352
|
|
|
|
|
|
|
code => sub { |
1353
|
4
|
50
|
33
|
6
|
|
15
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1354
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1355
|
4
|
|
|
|
|
14
|
my $self = shift; |
1356
|
4
|
|
100
|
|
|
32
|
$self->{$field} ||= {}; |
1357
|
4
|
|
|
|
|
5
|
keys %{ $self->{$field} }; |
|
4
|
|
|
|
|
43
|
|
1358
|
|
|
|
|
|
|
}, |
1359
|
2
|
|
|
|
|
43
|
); |
1360
|
|
|
|
|
|
|
} |
1361
|
|
|
|
|
|
|
$self->document_accessor( |
1362
|
1
|
|
|
|
|
69
|
name => \@elements_methods, |
1363
|
|
|
|
|
|
|
purpose => 'Returns the elements of the set.', |
1364
|
|
|
|
|
|
|
examples => ["my \@elements = \$obj->$elements_methods[0];"], |
1365
|
|
|
|
|
|
|
belongs_to => $field, |
1366
|
|
|
|
|
|
|
); |
1367
|
1
|
|
|
|
|
507
|
my @delete_methods = uniq "delete_${field}", "${field}_delete"; |
1368
|
1
|
|
|
|
|
3
|
for my $name (@delete_methods) { |
1369
|
|
|
|
|
|
|
$self->install_accessor( |
1370
|
|
|
|
|
|
|
name => $name, |
1371
|
|
|
|
|
|
|
code => sub { |
1372
|
1
|
50
|
33
|
7
|
|
6
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1373
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1374
|
1
|
|
|
|
|
3
|
my $self = shift; |
1375
|
1
|
|
|
|
|
7
|
delete $self->{$field}{$_} for @_; |
1376
|
|
|
|
|
|
|
}, |
1377
|
2
|
|
|
|
|
42
|
); |
1378
|
|
|
|
|
|
|
} |
1379
|
|
|
|
|
|
|
$self->document_accessor( |
1380
|
1
|
|
|
|
|
36
|
name => \@delete_methods, |
1381
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1382
|
|
|
|
|
|
|
If called with a list of values, it deletes those elements from the set. |
1383
|
|
|
|
|
|
|
EODOC |
1384
|
|
|
|
|
|
|
examples => ["\$obj->$delete_methods[0](\@elements);"], |
1385
|
|
|
|
|
|
|
belongs_to => $field, |
1386
|
|
|
|
|
|
|
); |
1387
|
1
|
|
|
|
|
582
|
my @clear_methods = uniq "clear_${field}", "${field}_clear"; |
1388
|
1
|
|
|
|
|
4
|
for my $name (@clear_methods) { |
1389
|
|
|
|
|
|
|
$self->install_accessor( |
1390
|
|
|
|
|
|
|
name => $name, |
1391
|
|
|
|
|
|
|
code => sub { |
1392
|
1
|
50
|
33
|
6
|
|
7
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1393
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1394
|
1
|
|
|
|
|
5
|
$_[0]->{$field} = {}; |
1395
|
|
|
|
|
|
|
}, |
1396
|
2
|
|
|
|
|
42
|
); |
1397
|
|
|
|
|
|
|
} |
1398
|
|
|
|
|
|
|
$self->document_accessor( |
1399
|
1
|
|
|
|
|
34
|
name => \@clear_methods, |
1400
|
|
|
|
|
|
|
purpose => 'Deletes all elements from the set.', |
1401
|
|
|
|
|
|
|
examples => ["\$obj->$clear_methods[0];"], |
1402
|
|
|
|
|
|
|
belongs_to => $field, |
1403
|
|
|
|
|
|
|
); |
1404
|
1
|
|
|
|
|
595
|
my @contains_methods = uniq "contains_${field}", "${field}_contains"; |
1405
|
1
|
|
|
|
|
5
|
for my $name (@contains_methods) { |
1406
|
|
|
|
|
|
|
$self->install_accessor( |
1407
|
|
|
|
|
|
|
name => $name, |
1408
|
|
|
|
|
|
|
code => sub { |
1409
|
4
|
50
|
33
|
6
|
|
16
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1410
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1411
|
4
|
|
|
|
|
8
|
my ($self, $key) = @_; |
1412
|
4
|
50
|
|
|
|
11
|
return unless defined $key; |
1413
|
4
|
|
|
|
|
34
|
exists $self->{$field}{$key}; |
1414
|
|
|
|
|
|
|
}, |
1415
|
2
|
|
|
|
|
41
|
); |
1416
|
|
|
|
|
|
|
} |
1417
|
|
|
|
|
|
|
$self->document_accessor( |
1418
|
1
|
|
|
|
|
30
|
name => \@contains_methods, |
1419
|
|
|
|
|
|
|
purpose => <<'EODOC', |
1420
|
|
|
|
|
|
|
Takes a single key and returns a boolean value indicating whether that key is |
1421
|
|
|
|
|
|
|
an element of the set. |
1422
|
|
|
|
|
|
|
EODOC |
1423
|
|
|
|
|
|
|
examples => ["if (\$obj->$contains_methods[0](\$element)) { ... }"], |
1424
|
|
|
|
|
|
|
, |
1425
|
|
|
|
|
|
|
belongs_to => $field, |
1426
|
|
|
|
|
|
|
); |
1427
|
1
|
|
|
|
|
444
|
my @is_empty_methods = uniq "is_empty_${field}", "${field}_is_empty"; |
1428
|
1
|
|
|
|
|
23
|
for my $name (@is_empty_methods) { |
1429
|
|
|
|
|
|
|
$self->install_accessor( |
1430
|
|
|
|
|
|
|
name => $name, |
1431
|
|
|
|
|
|
|
code => sub { |
1432
|
2
|
50
|
33
|
7
|
|
569
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1433
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1434
|
2
|
|
|
|
|
5
|
my $self = shift; |
1435
|
2
|
50
|
|
|
|
4
|
keys %{ $self->{$field} || {} } == 0; |
|
2
|
|
|
|
|
20
|
|
1436
|
|
|
|
|
|
|
}, |
1437
|
2
|
|
|
|
|
38
|
); |
1438
|
|
|
|
|
|
|
} |
1439
|
|
|
|
|
|
|
$self->document_accessor( |
1440
|
1
|
|
|
|
|
30
|
name => \@is_empty_methods, |
1441
|
|
|
|
|
|
|
purpose => |
1442
|
|
|
|
|
|
|
'Returns a boolean value indicating whether the set is empty of not.', |
1443
|
|
|
|
|
|
|
examples => ["\$obj->$is_empty_methods[0];"], |
1444
|
|
|
|
|
|
|
belongs_to => $field, |
1445
|
|
|
|
|
|
|
); |
1446
|
1
|
|
|
|
|
523
|
my @size_methods = uniq "size_${field}", "${field}_size"; |
1447
|
1
|
|
|
|
|
4
|
for my $name (@size_methods) { |
1448
|
|
|
|
|
|
|
$self->install_accessor( |
1449
|
|
|
|
|
|
|
name => $name, |
1450
|
|
|
|
|
|
|
code => sub { |
1451
|
4
|
50
|
33
|
10
|
|
16
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1452
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1453
|
4
|
|
|
|
|
6
|
my $self = shift; |
1454
|
4
|
50
|
|
|
|
5
|
scalar keys %{ $self->{$field} || {} }; |
|
4
|
|
|
|
|
28
|
|
1455
|
|
|
|
|
|
|
}, |
1456
|
2
|
|
|
|
|
38
|
); |
1457
|
|
|
|
|
|
|
} |
1458
|
|
|
|
|
|
|
$self->document_accessor( |
1459
|
1
|
|
|
|
|
28
|
name => \@size_methods, |
1460
|
|
|
|
|
|
|
purpose => 'Returns the number of elements in the set.', |
1461
|
|
|
|
|
|
|
examples => ["my \$size = \$obj->$size_methods[0];"], |
1462
|
|
|
|
|
|
|
belongs_to => $field, |
1463
|
|
|
|
|
|
|
); |
1464
|
|
|
|
|
|
|
} |
1465
|
1
|
|
|
|
|
435
|
$self; # for chaining |
1466
|
|
|
|
|
|
|
} |
1467
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
sub mk_object_accessors { |
1469
|
2
|
|
|
8
|
1
|
10
|
my ($self, @args) = @_; |
1470
|
2
|
|
33
|
|
|
18
|
my $class = ref $self || $self; |
1471
|
2
|
|
|
|
|
8
|
while (@args) { |
1472
|
3
|
|
|
|
|
466
|
my $type = shift @args; |
1473
|
3
|
50
|
|
|
|
13
|
my $list = shift @args or die "No slot names for $class"; |
1474
|
|
|
|
|
|
|
|
1475
|
|
|
|
|
|
|
# Allow a list of hashrefs. |
1476
|
3
|
50
|
|
|
|
53
|
my @list = ref($list) eq 'ARRAY' ? @$list : ($list); |
1477
|
3
|
|
|
|
|
8
|
for my $obj_def (@list) { |
1478
|
3
|
|
|
|
|
3
|
my ($name, @composites); |
1479
|
3
|
100
|
|
|
|
10
|
if (!ref $obj_def) { |
1480
|
2
|
|
|
|
|
3
|
$name = $obj_def; |
1481
|
|
|
|
|
|
|
} else { |
1482
|
1
|
|
|
|
|
4
|
$name = $obj_def->{slot}; |
1483
|
1
|
|
|
|
|
2
|
my $composites = $obj_def->{comp_mthds}; |
1484
|
1
|
0
|
|
|
|
6
|
@composites = |
|
|
50
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
ref($composites) eq 'ARRAY' ? @$composites |
1486
|
|
|
|
|
|
|
: defined $composites ? ($composites) |
1487
|
|
|
|
|
|
|
: (); |
1488
|
|
|
|
|
|
|
} |
1489
|
3
|
|
|
|
|
8
|
for my $meth (@composites) { |
1490
|
|
|
|
|
|
|
$self->install_accessor( |
1491
|
|
|
|
|
|
|
name => $meth, |
1492
|
|
|
|
|
|
|
code => sub { |
1493
|
1
|
50
|
33
|
5
|
|
7
|
local $DB::sub = local *__ANON__ = "${class}::{$meth}" |
1494
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1495
|
1
|
|
|
|
|
2
|
my ($self, @args) = @_; |
1496
|
1
|
|
|
|
|
4
|
$self->$name()->$meth(@args); |
1497
|
|
|
|
|
|
|
}, |
1498
|
2
|
|
|
|
|
475
|
); |
1499
|
2
|
|
|
|
|
68
|
$self->document_accessor( |
1500
|
|
|
|
|
|
|
name => $meth, |
1501
|
|
|
|
|
|
|
purpose => <
|
1502
|
|
|
|
|
|
|
Calls $meth() with the given arguments on the object stored in the $name slot. |
1503
|
|
|
|
|
|
|
If there is no such object, a new $type object is constructed - no arguments |
1504
|
|
|
|
|
|
|
are passed to the constructor - and stored in the $name slot before forwarding |
1505
|
|
|
|
|
|
|
$meth() onto it. |
1506
|
|
|
|
|
|
|
EODOC |
1507
|
|
|
|
|
|
|
examples => [ "\$obj->$meth(\@args);", "\$obj->$meth;", ], |
1508
|
|
|
|
|
|
|
); |
1509
|
|
|
|
|
|
|
} |
1510
|
|
|
|
|
|
|
$self->install_accessor( |
1511
|
|
|
|
|
|
|
name => $name, |
1512
|
|
|
|
|
|
|
code => sub { |
1513
|
12
|
50
|
33
|
13
|
|
1010
|
local $DB::sub = local *__ANON__ = "${class}::${name}" |
1514
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1515
|
12
|
|
|
|
|
56
|
my ($self, @args) = @_; |
1516
|
12
|
50
|
33
|
|
|
38
|
if (ref($args[0]) && UNIVERSAL::isa($args[0], $type)) { |
1517
|
0
|
|
|
|
|
0
|
$self->{$name} = $args[0]; |
1518
|
|
|
|
|
|
|
} else { |
1519
|
12
|
100
|
|
|
|
56
|
defined $self->{$name} |
1520
|
|
|
|
|
|
|
or $self->{$name} = $type->new(@args); |
1521
|
|
|
|
|
|
|
} |
1522
|
12
|
|
|
|
|
57
|
$self->{$name}; |
1523
|
|
|
|
|
|
|
}, |
1524
|
3
|
|
|
|
|
492
|
); |
1525
|
3
|
|
|
|
|
108
|
$self->document_accessor( |
1526
|
|
|
|
|
|
|
name => $name, |
1527
|
|
|
|
|
|
|
purpose => <
|
1528
|
|
|
|
|
|
|
If called with an argument object of type $type it sets the object; further |
1529
|
|
|
|
|
|
|
arguments are discarded. If called with arguments but the first argument is |
1530
|
|
|
|
|
|
|
not an object of type $type, a new object of type $type is constructed and the |
1531
|
|
|
|
|
|
|
arguments are passed to the constructor. |
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
If called without arguments, it returns the $type object stored in this slot; |
1534
|
|
|
|
|
|
|
if there is no such object, a new $type object is constructed - no arguments |
1535
|
|
|
|
|
|
|
are passed to the constructor in this case - and stored in the $name slot |
1536
|
|
|
|
|
|
|
before returning it. |
1537
|
|
|
|
|
|
|
EODOC |
1538
|
|
|
|
|
|
|
examples => [ |
1539
|
|
|
|
|
|
|
"my \$object = \$obj->$name;", "\$obj->$name(\$object);", |
1540
|
|
|
|
|
|
|
"\$obj->$name(\@args);", |
1541
|
|
|
|
|
|
|
], |
1542
|
|
|
|
|
|
|
); |
1543
|
3
|
|
|
|
|
1326
|
my @clear_methods = uniq "clear_${name}", "${name}_clear"; |
1544
|
3
|
|
|
|
|
12
|
for my $meth (@clear_methods) { |
1545
|
|
|
|
|
|
|
$self->install_accessor( |
1546
|
|
|
|
|
|
|
name => $meth, |
1547
|
|
|
|
|
|
|
code => sub { |
1548
|
0
|
0
|
0
|
13
|
|
0
|
local $DB::sub = local *__ANON__ = "${class}::${meth}" |
1549
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1550
|
0
|
|
|
|
|
0
|
delete $_[0]->{$name}; |
1551
|
|
|
|
|
|
|
}, |
1552
|
6
|
|
|
|
|
147
|
); |
1553
|
|
|
|
|
|
|
} |
1554
|
|
|
|
|
|
|
$self->document_accessor( |
1555
|
3
|
|
|
|
|
101
|
name => \@clear_methods, |
1556
|
|
|
|
|
|
|
purpose => 'Deletes the object.', |
1557
|
|
|
|
|
|
|
examples => "\$obj->$clear_methods[0];", |
1558
|
|
|
|
|
|
|
belongs_to => $name, |
1559
|
|
|
|
|
|
|
); |
1560
|
|
|
|
|
|
|
} |
1561
|
|
|
|
|
|
|
} |
1562
|
2
|
|
|
|
|
864
|
$self; # for chaining |
1563
|
|
|
|
|
|
|
} |
1564
|
|
|
|
|
|
|
|
1565
|
|
|
|
|
|
|
sub mk_forward_accessors { |
1566
|
1
|
|
|
10
|
1
|
4
|
my ($self, %args) = @_; |
1567
|
1
|
|
33
|
|
|
6
|
my $class = ref $self || $self; |
1568
|
1
|
|
|
|
|
6
|
while (my ($slot, $methods) = each %args) { |
1569
|
2
|
100
|
|
|
|
420
|
my @methods = ref $methods eq 'ARRAY' ? @$methods : ($methods); |
1570
|
2
|
|
|
|
|
3
|
for my $field (@methods) { |
1571
|
|
|
|
|
|
|
$self->install_accessor( |
1572
|
|
|
|
|
|
|
name => $field, |
1573
|
|
|
|
|
|
|
code => sub { |
1574
|
3
|
50
|
33
|
3
|
|
19
|
local $DB::sub = local *__ANON__ = "${class}::${field}" |
1575
|
|
|
|
|
|
|
if defined &DB::DB && !$Devel::DProf::VERSION; |
1576
|
3
|
|
|
|
|
6
|
my ($self, @args) = @_; |
1577
|
3
|
|
|
|
|
7
|
$self->$slot()->$field(@args); |
1578
|
|
|
|
|
|
|
}, |
1579
|
3
|
|
|
|
|
422
|
); |
1580
|
3
|
|
|
|
|
79
|
$self->document_accessor( |
1581
|
|
|
|
|
|
|
name => $field, |
1582
|
|
|
|
|
|
|
purpose => <
|
1583
|
|
|
|
|
|
|
Calls $field() with the given arguments on the object stored in the $slot |
1584
|
|
|
|
|
|
|
slot. |
1585
|
|
|
|
|
|
|
EODOC |
1586
|
|
|
|
|
|
|
examples => [ "\$obj->$field(\@args);", "\$obj->$field;", ], |
1587
|
|
|
|
|
|
|
); |
1588
|
|
|
|
|
|
|
} |
1589
|
|
|
|
|
|
|
} |
1590
|
1
|
|
|
|
|
412
|
$self; # for chaining |
1591
|
|
|
|
|
|
|
} |
1592
|
|
|
|
|
|
|
1; |
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
|
1595
|
|
|
|
|
|
|
__END__ |