| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# Schedule::Load::Hosts::Host.pm -- Loading information about a host |
|
2
|
|
|
|
|
|
|
# See copyright, etc in below POD section. |
|
3
|
|
|
|
|
|
|
###################################################################### |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Schedule::Load::Hosts::Host; |
|
6
|
|
|
|
|
|
|
require 5.004; |
|
7
|
|
|
|
|
|
|
require Exporter; |
|
8
|
|
|
|
|
|
|
require AutoLoader; |
|
9
|
|
|
|
|
|
|
@ISA = qw(Exporter AutoLoader); |
|
10
|
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
6
|
use Schedule::Load qw(_min _max); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
52
|
|
|
12
|
1
|
|
|
1
|
|
557
|
use Schedule::Load::Hosts::Proc; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
40
|
|
|
13
|
1
|
|
|
1
|
|
407
|
use Schedule::Load::Safe; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
36
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
64
|
|
|
16
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
36
|
|
|
17
|
1
|
|
|
1
|
|
6
|
use vars qw($VERSION $AUTOLOAD $Debug $Safer); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
1952
|
|
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
###################################################################### |
|
20
|
|
|
|
|
|
|
#### Configuration Section |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# Other configurable settings. |
|
23
|
|
|
|
|
|
|
$VERSION = '3.064'; |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
###################################################################### |
|
26
|
|
|
|
|
|
|
#### Globals |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
$Debug = $Schedule::Load::Debug; |
|
29
|
|
|
|
|
|
|
$Safer = Schedule::Load::Safe->new(); |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
###################################################################### |
|
32
|
|
|
|
|
|
|
#### Special status |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub fields { |
|
35
|
2
|
50
|
33
|
2
|
1
|
3
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->hosts)'; |
|
|
2
|
|
|
|
|
15
|
|
|
36
|
2
|
|
|
|
|
3
|
my @keys = keys %{$self->{const}}; |
|
|
2
|
|
|
|
|
25
|
|
|
37
|
2
|
|
|
|
|
6
|
push @keys, keys %{$self->{stored}}; |
|
|
2
|
|
|
|
|
8
|
|
|
38
|
2
|
|
|
|
|
4
|
push @keys, keys %{$self->{dynamic}}; |
|
|
2
|
|
|
|
|
13
|
|
|
39
|
2
|
|
|
|
|
6
|
return (grep {$_ ne "procs"} @keys); |
|
|
64
|
|
|
|
|
131
|
|
|
40
|
|
|
|
|
|
|
} |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub exists { |
|
43
|
2
|
50
|
33
|
2
|
1
|
3
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->get(field))'; |
|
|
2
|
|
|
|
|
20
|
|
|
44
|
2
|
|
|
|
|
3
|
my $field = shift; |
|
45
|
2
|
|
33
|
|
|
64
|
return (exists ($self->{dynamic}{$field}) |
|
46
|
|
|
|
|
|
|
|| exists ($self->{stored}{$field}) |
|
47
|
|
|
|
|
|
|
|| exists ($self->{const}{$field})); |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub get { |
|
51
|
2
|
50
|
33
|
2
|
1
|
4
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->get(field))'; |
|
|
2
|
|
|
|
|
52
|
|
|
52
|
2
|
|
|
|
|
3
|
my $field = shift; |
|
53
|
|
|
|
|
|
|
# Always look at dynamic info first, there might be a override of a const |
|
54
|
2
|
50
|
|
|
|
21
|
if (exists ($self->{dynamic}{$field})) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
0
|
return $self->{dynamic}{$field}; |
|
56
|
|
|
|
|
|
|
} elsif (exists ($self->{stored}{$field})) { |
|
57
|
0
|
|
|
|
|
0
|
return $self->{stored}{$field}; |
|
58
|
|
|
|
|
|
|
} elsif (exists ($self->{const}{$field})) { |
|
59
|
2
|
|
|
|
|
15
|
return $self->{const}{$field}; |
|
60
|
|
|
|
|
|
|
} else { |
|
61
|
0
|
|
|
|
|
0
|
croak __PACKAGE__.'->get($field): Unknown field'; |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub get_undef { |
|
66
|
24
|
50
|
33
|
24
|
0
|
34
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->get(field))'; |
|
|
24
|
|
|
|
|
121
|
|
|
67
|
24
|
|
|
|
|
56
|
my $field = shift; |
|
68
|
|
|
|
|
|
|
# Always look at dynamic info first, there might be a override of a const |
|
69
|
24
|
50
|
|
|
|
118
|
if (exists ($self->{dynamic}{$field})) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
0
|
return $self->{dynamic}{$field}; |
|
71
|
|
|
|
|
|
|
} elsif (exists ($self->{stored}{$field})) { |
|
72
|
0
|
|
|
|
|
0
|
return $self->{stored}{$field}; |
|
73
|
|
|
|
|
|
|
} elsif (exists ($self->{const}{$field})) { |
|
74
|
12
|
|
|
|
|
201
|
return $self->{const}{$field}; |
|
75
|
|
|
|
|
|
|
} else { |
|
76
|
12
|
|
|
|
|
57
|
return undef; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
###################################################################### |
|
81
|
|
|
|
|
|
|
#### Matching |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub host_match { |
|
84
|
14
|
50
|
33
|
14
|
0
|
23
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->host_match(classesref))'; |
|
|
14
|
|
|
|
|
77
|
|
|
85
|
|
|
|
|
|
|
# Params can be either a hash reference (for chooser) |
|
86
|
|
|
|
|
|
|
# or a list of parameters (simple user functions) |
|
87
|
14
|
|
|
|
|
32
|
my $paramref = $_[0]; |
|
88
|
14
|
50
|
|
|
|
34
|
if (!ref $paramref) { |
|
89
|
14
|
|
|
|
|
41
|
$paramref = {#classes=>[], |
|
90
|
|
|
|
|
|
|
#match_cb=> undef, |
|
91
|
|
|
|
|
|
|
#allow_reserved=>1, |
|
92
|
|
|
|
|
|
|
@_, |
|
93
|
|
|
|
|
|
|
}; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
# For use of Hosts::hosts_match |
|
96
|
14
|
|
33
|
|
|
227
|
return ((!defined $paramref->{classes} || $self->classes_match($paramref->{classes})) |
|
97
|
|
|
|
|
|
|
&& (!defined $paramref->{match_cb} || $self->eval_match ($paramref->{match_cb})) |
|
98
|
|
|
|
|
|
|
&& (!defined $paramref->{allow_reserved} || $paramref->{allow_reserved} |
|
99
|
|
|
|
|
|
|
|| !$self->reserved) |
|
100
|
|
|
|
|
|
|
); |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub host_match_chooser { |
|
104
|
0
|
|
|
0
|
0
|
0
|
my $self = $_[0]; |
|
105
|
|
|
|
|
|
|
# Similar to host_match, but for internal use by the chooser - performance critical |
|
106
|
0
|
|
|
|
|
0
|
my $paramref = $_[1]; |
|
107
|
0
|
|
|
|
|
0
|
my $scratchref = $_[2]; |
|
108
|
|
|
|
|
|
|
# For use of Hosts::hosts_match |
|
109
|
0
|
|
0
|
|
|
0
|
return (( !defined $paramref->{classes} || !defined $paramref->{classes}[0] |
|
110
|
|
|
|
|
|
|
|| _classes_match_chooser($self, $paramref->{classes}) |
|
111
|
|
|
|
|
|
|
) |
|
112
|
|
|
|
|
|
|
&& (!defined $paramref->{match_cb} |
|
113
|
|
|
|
|
|
|
#Slow, so inlined: || $self->eval_match ($paramref->{match_cb}, $scratchref) |
|
114
|
|
|
|
|
|
|
|| _eval_generic_cb($self, $paramref->{match_cb}, $scratchref) |
|
115
|
|
|
|
|
|
|
) |
|
116
|
|
|
|
|
|
|
&& (!defined $paramref->{allow_reserved} || $paramref->{allow_reserved} |
|
117
|
|
|
|
|
|
|
|| !$self->reserved) |
|
118
|
|
|
|
|
|
|
); |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub classes_match { |
|
122
|
6
|
50
|
33
|
6
|
1
|
13
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->classes_match(classesref))'; |
|
|
6
|
|
|
|
|
44
|
|
|
123
|
6
|
|
|
|
|
10
|
my $classesref = shift; |
|
124
|
6
|
50
|
33
|
|
|
40
|
return 1 if !defined $classesref || !defined $classesref->[0]; # Null reference means match everything |
|
125
|
6
|
50
|
|
|
|
18
|
(ref($classesref)) or croak 'usage: '.__PACKAGE__.'->classes_match(field, classesref))'; |
|
126
|
6
|
|
|
|
|
8
|
foreach (@{$classesref}) { |
|
|
6
|
|
|
|
|
14
|
|
|
127
|
6
|
50
|
|
|
|
16
|
return 1 if get_undef($self, $_); |
|
128
|
|
|
|
|
|
|
} |
|
129
|
0
|
|
|
|
|
0
|
return 0; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub _classes_match_chooser { |
|
133
|
0
|
|
|
0
|
|
0
|
my $self = $_[0]; |
|
134
|
0
|
|
|
|
|
0
|
my $classesref = $_[1]; |
|
135
|
0
|
|
|
|
|
0
|
foreach (@{$classesref}) { |
|
|
0
|
|
|
|
|
0
|
|
|
136
|
0
|
0
|
|
|
|
0
|
return 1 if get_undef($self, $_); |
|
137
|
|
|
|
|
|
|
} |
|
138
|
0
|
|
|
|
|
0
|
return 0; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub eval_match { |
|
142
|
4
|
50
|
33
|
4
|
1
|
120
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->eval_match(subroutine)'; |
|
|
4
|
|
|
|
|
29
|
|
|
143
|
4
|
|
|
|
|
6
|
my $subref = shift; |
|
144
|
|
|
|
|
|
|
# @_ are optional arguments |
|
145
|
|
|
|
|
|
|
# See inlined version in host_match_chooser |
|
146
|
4
|
50
|
|
|
|
8
|
return 1 if !defined $subref; # Null reference means match everything |
|
147
|
4
|
|
|
|
|
10
|
return $self->_eval_generic_cb($subref,@_); |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub _eval_generic_cb { |
|
151
|
4
|
|
|
4
|
|
7
|
my $self = shift; |
|
152
|
4
|
|
|
|
|
4
|
my $subref = shift; |
|
153
|
|
|
|
|
|
|
# @_ are optional arguments |
|
154
|
|
|
|
|
|
|
# Call &$subref($self) in safe container |
|
155
|
4
|
|
|
|
|
34
|
return $Safer->eval_cb($subref,$self,@_); |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
###################################################################### |
|
159
|
|
|
|
|
|
|
#### Special accessors |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub cpus_slash { |
|
162
|
2
|
|
|
2
|
1
|
5
|
my $self = shift; |
|
163
|
2
|
50
|
|
|
|
27
|
if ($self->cpus != $self->physical_cpus) { |
|
164
|
0
|
|
|
|
|
0
|
return $self->physical_cpus."/".$self->cpus; |
|
165
|
|
|
|
|
|
|
} else { |
|
166
|
2
|
|
|
|
|
126
|
return $self->cpus; |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub top_processes { |
|
171
|
2
|
50
|
33
|
2
|
1
|
3
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->key(key))'; |
|
|
2
|
|
|
|
|
19
|
|
|
172
|
2
|
|
|
|
|
3
|
my @keys = (values %{$self->{dynamic}{proc}}); |
|
|
2
|
|
|
|
|
8
|
|
|
173
|
2
|
|
|
|
|
4
|
grep {bless $_, 'Schedule::Load::Hosts::Proc'} @keys; |
|
|
1
|
|
|
|
|
19
|
|
|
174
|
|
|
|
|
|
|
#print "TOP PROC @keys\n"; |
|
175
|
2
|
50
|
|
|
|
13
|
return (wantarray ? @keys : \@keys); |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub holds { |
|
179
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
180
|
0
|
0
|
|
|
|
0
|
return if !$self->{dynamic}{holds}; |
|
181
|
0
|
|
|
|
|
0
|
return (sort {$a->compare_pri_time($b)} (@{$self->{dynamic}{holds}})); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub free_cpus { |
|
185
|
8
|
|
|
8
|
0
|
15
|
my $self = shift; |
|
186
|
|
|
|
|
|
|
# How many more jobs host can take before we should turn off new jobs |
|
187
|
8
|
|
|
|
|
151
|
my $free = ($self->cpus - $self->adj_load); |
|
188
|
8
|
50
|
|
|
|
22
|
$free = 0 if ($free < 0); |
|
189
|
8
|
|
|
|
|
25
|
$free = int ($free + .7); |
|
190
|
8
|
|
|
|
|
25
|
return $free; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
sub rating_cb { |
|
194
|
4
|
50
|
33
|
4
|
0
|
5
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->key(key))'; |
|
|
4
|
|
|
|
|
29
|
|
|
195
|
|
|
|
|
|
|
# How fast can we process a single job? |
|
196
|
|
|
|
|
|
|
# 0 indicates can't load this host |
|
197
|
|
|
|
|
|
|
# closer to 0 are the best ratings (as 'bad' is open-ended) |
|
198
|
4
|
50
|
33
|
|
|
11
|
if ($self->get_undef('load_limit') |
|
199
|
|
|
|
|
|
|
&& $self->load_limit <= $self->adj_load) { |
|
200
|
|
|
|
|
|
|
# Illegal to load this host more |
|
201
|
0
|
|
|
|
|
0
|
return 0; |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
|
|
204
|
4
|
|
|
|
|
6
|
my $rate = 1e9; |
|
205
|
|
|
|
|
|
|
# Multiply badness by cpu loading |
|
206
|
|
|
|
|
|
|
# Scale it to be between .8 and 1.0, else a large number of inactive jobs would |
|
207
|
|
|
|
|
|
|
# result in a very good rating, which would make that machine always be picked. |
|
208
|
4
|
|
|
|
|
82
|
$rate *= ((($self->total_pctcpu+1)/100) * 0.2 + 0.8); |
|
209
|
|
|
|
|
|
|
# Multiply that by number of jobs |
|
210
|
4
|
|
|
|
|
80
|
$rate *= ($self->adj_load+1); |
|
211
|
|
|
|
|
|
|
# Discount by cpus & frequency |
|
212
|
4
|
|
|
|
|
72
|
$rate /= $self->cpus; |
|
213
|
4
|
|
|
|
|
78
|
$rate /= $self->max_clock * 0.4; # 1 free cpu at 300Mhz beat 50% of a 600 Mhz cpu |
|
214
|
4
|
|
50
|
|
|
10
|
$rate *= ($self->get_undef('rating_mult') || 1.0); |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
#printf "%f * (%d+%d+1) / %f / %f = %f\n", ($self->total_pctcpu+1), $self->report_load, $self->adj_load, $self->cpus, $self->max_clock, $rate if $Debug; |
|
217
|
4
|
50
|
|
|
|
12
|
return 0 if $rate<=0; |
|
218
|
4
|
|
|
|
|
9
|
$rate = log($rate); # Make a more readable number |
|
219
|
4
|
|
50
|
|
|
9
|
$rate += ($self->get_undef('rating_adder') || 0); |
|
220
|
4
|
|
|
|
|
50
|
return $rate; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub rating { |
|
224
|
4
|
50
|
33
|
4
|
0
|
7
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->rating(subroutine)'; |
|
|
4
|
|
|
|
|
29
|
|
|
225
|
4
|
|
|
|
|
5
|
my $subref = shift; |
|
226
|
4
|
50
|
|
|
|
18
|
return $self->rating_cb() if !defined $subref; # Null reference means default callback |
|
227
|
0
|
|
|
|
|
0
|
return $self->_eval_generic_cb($subref); |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
sub rating_chooser { |
|
231
|
|
|
|
|
|
|
# Similar to rating, but for internal use by the chooser - performance critical |
|
232
|
0
|
|
|
0
|
0
|
0
|
my $self = $_[0]; |
|
233
|
0
|
|
|
|
|
0
|
my $subref = $_[1]; |
|
234
|
0
|
|
|
|
|
0
|
my $scratchref = $_[2]; |
|
235
|
0
|
0
|
|
|
|
0
|
return $self->rating_cb() if !defined $subref; # Null reference means default callback |
|
236
|
0
|
|
|
|
|
0
|
return $self->_eval_generic_cb($subref, $scratchref); |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub rating_text { |
|
240
|
2
|
50
|
33
|
2
|
0
|
5
|
my $self = shift; ($self && ref($self)) or croak 'usage: '.__PACKAGE__.'->rating(subroutine)'; |
|
|
2
|
|
|
|
|
23
|
|
|
241
|
2
|
50
|
|
|
|
44
|
return "inf" if $self->reserved; |
|
242
|
2
|
50
|
|
|
|
6
|
return "inf" if !$self->rating; |
|
243
|
2
|
50
|
|
|
|
4
|
return "slow" if $self->get_undef('slreportd_unresponsive'); |
|
244
|
2
|
|
|
|
|
6
|
return sprintf("%4.2f", $self->rating); |
|
245
|
|
|
|
|
|
|
} |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
###################################################################### |
|
248
|
|
|
|
|
|
|
#### Accessors |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub AUTOLOAD { |
|
251
|
10
|
|
|
10
|
|
14
|
my $self = shift; |
|
252
|
10
|
50
|
|
|
|
26
|
my $type = ref($self) or croak "$self is not an ".__PACKAGE__." object"; |
|
253
|
|
|
|
|
|
|
|
|
254
|
10
|
|
|
|
|
50
|
(my $field = $AUTOLOAD) =~ s/.*://; # Remove package |
|
255
|
|
|
|
|
|
|
|
|
256
|
10
|
100
|
|
|
|
53
|
if (exists ($self->{dynamic}{$field})) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
# Dynamic variables stay dynamic |
|
258
|
2
|
|
|
15
|
1
|
69
|
eval "sub $field { return \$_[0]->{dynamic}{$field}; }"; |
|
|
15
|
|
|
5
|
1
|
183
|
|
|
|
5
|
|
|
|
|
63
|
|
|
259
|
2
|
|
|
|
|
61
|
return $self->{dynamic}{$field}; |
|
260
|
|
|
|
|
|
|
} elsif (exists ($self->{stored}{$field})) { |
|
261
|
|
|
|
|
|
|
# Stored variables can move to/from const variables |
|
262
|
1
|
50
|
|
15
|
1
|
80
|
eval "sub $field { return (exists \$_[0]->{stored}{$field} " |
|
|
15
|
|
|
|
|
139
|
|
|
263
|
|
|
|
|
|
|
."? \$_[0]->{stored}{$field} : \$_[0]->{const}{$field}); }"; |
|
264
|
1
|
|
|
|
|
12
|
return $self->{stored}{$field}; |
|
265
|
|
|
|
|
|
|
} elsif (exists ($self->{const}{$field})) { |
|
266
|
7
|
50
|
|
1
|
1
|
602
|
eval "sub $field { return (exists \$_[0]->{stored}{$field} " |
|
|
1
|
50
|
|
25
|
1
|
24
|
|
|
|
25
|
50
|
|
142
|
1
|
295
|
|
|
|
142
|
50
|
|
5
|
1
|
1348
|
|
|
|
5
|
50
|
|
1
|
0
|
40
|
|
|
|
1
|
50
|
|
1
|
1
|
7
|
|
|
|
1
|
50
|
|
2
|
1
|
7
|
|
|
|
2
|
|
|
|
|
20
|
|
|
267
|
|
|
|
|
|
|
."? \$_[0]->{stored}{$field} : \$_[0]->{const}{$field}); }"; |
|
268
|
7
|
|
|
|
|
121
|
return $self->{const}{$field}; |
|
269
|
|
|
|
|
|
|
} else { |
|
270
|
0
|
|
|
|
|
0
|
croak "$type->$field: Unknown ".__PACKAGE__." field $field"; |
|
271
|
|
|
|
|
|
|
} |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
|
|
274
|
0
|
|
|
0
|
|
|
sub DESTROY {} |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
###################################################################### |
|
277
|
|
|
|
|
|
|
###################################################################### |
|
278
|
|
|
|
|
|
|
#### Package return |
|
279
|
|
|
|
|
|
|
1; |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
###################################################################### |
|
282
|
|
|
|
|
|
|
__END__ |