line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
=head1 NAME
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
Math::Sequence - Perl extension dealing with mathematic sequences
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
use Math::Sequence;
|
9
|
|
|
|
|
|
|
my $x_n = Math::Sequence->new('x^2 - 1', 2);
|
10
|
|
|
|
|
|
|
print $x_n->next(), "\n" foreach 0..9;
|
11
|
|
|
|
|
|
|
# prints 2, 3, 8, 63...
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
print $x_n->at_index(5);
|
14
|
|
|
|
|
|
|
# prints 15745023
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
$x_n->cached(0); # don't cache the results (slow!)
|
17
|
|
|
|
|
|
|
$x_n->cached(1); # cache the results (default)
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Math::Sequence defines a class for simple mathematic sequences with a
|
22
|
|
|
|
|
|
|
recursive definition such as C. Creation of a
|
23
|
|
|
|
|
|
|
Math::Sequence object is described below in the paragraph about the
|
24
|
|
|
|
|
|
|
constructor.
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
Math::Sequence uses Math::Symbolic to parse and modify the recursive
|
27
|
|
|
|
|
|
|
sequence definitions. That means you specify the sequence as a string which
|
28
|
|
|
|
|
|
|
is parsed by Math::Symbolic. Alternatively, you can pass the constructor
|
29
|
|
|
|
|
|
|
a Math::Symbolic tree directly.
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
Because Math::Sequence uses Math::Symbolic for its implementation, all results
|
32
|
|
|
|
|
|
|
will be Math::Symbolic objects which may contain other variables than the
|
33
|
|
|
|
|
|
|
sequence variable itself.
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Each Math::Sequence object is an iterator to iterate over the elements of the
|
36
|
|
|
|
|
|
|
sequence starting at the first element (which was specified by the starting
|
37
|
|
|
|
|
|
|
element, the second argument to the new() constructor). It offers
|
38
|
|
|
|
|
|
|
facilities to cache all calculated elements and access any element directly,
|
39
|
|
|
|
|
|
|
though unless the element has been cached in a previous calculation, this
|
40
|
|
|
|
|
|
|
is just a shortcut for repeated use of the iterator.
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
Every element in the sequence may only access its predecessor, not the elements
|
43
|
|
|
|
|
|
|
before that.
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head2 EXAMPLE
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
use strict;
|
48
|
|
|
|
|
|
|
use warnings;
|
49
|
|
|
|
|
|
|
use Math::Sequence;
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my $seq = Math::Sequence->new('x+a', 0, 'x');
|
52
|
|
|
|
|
|
|
print($seq->current_index(), ' => ', $seq->next(), "\n") for 1..10;
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=cut
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
package Math::Sequence;
|
57
|
|
|
|
|
|
|
|
58
|
1
|
|
|
1
|
|
859
|
use 5.006;
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
36
|
|
59
|
1
|
|
|
1
|
|
5
|
use strict;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
30
|
|
60
|
1
|
|
|
1
|
|
24
|
use warnings;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
62
|
|
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
our $VERSION = '1.00';
|
63
|
|
|
|
|
|
|
|
64
|
1
|
|
|
1
|
|
6
|
use Carp;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
98
|
|
65
|
|
|
|
|
|
|
|
66
|
1
|
|
|
1
|
|
943
|
use Math::Symbolic qw/:all/;
|
|
1
|
|
|
|
|
157433
|
|
|
1
|
|
|
|
|
1671
|
|
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=head2 CLASS DATA
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Math::Sequence defines the following package variables:
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=over 2
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item $Math::Sequence::Parser
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
This scalar contains a Parse::RecDescent parser to parse formulas.
|
77
|
|
|
|
|
|
|
It is derived from the Math::Symbolic::Parser grammar.
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=cut
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
our $Parser = Math::Symbolic::Parser->new();
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
#$Parser->Extend(<<'GRAMMAR');
|
84
|
|
|
|
|
|
|
#GRAMMAR
|
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=item $Math::Sequence::warnings
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
This scalar indicates whether Math::Sequence should warn about the performance
|
89
|
|
|
|
|
|
|
implications of using the back() method on uncached sequences. It defaults
|
90
|
|
|
|
|
|
|
to true.
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=cut
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
our $warnings = 1;
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=pod
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=back
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 METHODS
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=over 2
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item new()
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
The constructor for Math::Sequence objects. Takes two or three arguments.
|
107
|
|
|
|
|
|
|
In the two argument form, the first argument specifies the recursion
|
108
|
|
|
|
|
|
|
definition. It must be either a string to be parsed by a Math::Symbolic
|
109
|
|
|
|
|
|
|
parser or a Math::Symbolic tree. In the two argument version, the
|
110
|
|
|
|
|
|
|
recursion variable (the one which will be recursively replaced by its
|
111
|
|
|
|
|
|
|
predecessor) will be inferred from the function signature. Thus, the formula
|
112
|
|
|
|
|
|
|
must contain exactly one variable. The second argument must be a starting
|
113
|
|
|
|
|
|
|
value. It may either be a constant or a Math::Symbolic tree or a string to be
|
114
|
|
|
|
|
|
|
parsed as such.
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
The three argument version adds to the two argument version a string indicating
|
117
|
|
|
|
|
|
|
a variable name to be used as the recursion variable. Then, the recursion
|
118
|
|
|
|
|
|
|
formula may contain any number of variables.
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=cut
|
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub new {
|
123
|
4
|
|
|
4
|
1
|
2176
|
my $proto = shift;
|
124
|
4
|
|
33
|
|
|
29
|
my $class = ref($proto) || $proto;
|
125
|
|
|
|
|
|
|
|
126
|
4
|
|
|
|
|
7
|
my $formula = shift;
|
127
|
4
|
50
|
|
|
|
12
|
croak "Sequence->new() takes a formula as first argument."
|
128
|
|
|
|
|
|
|
if not defined $formula;
|
129
|
|
|
|
|
|
|
|
130
|
4
|
|
|
|
|
33
|
my $parsed = $Parser->parse($formula);
|
131
|
4
|
50
|
|
|
|
18253
|
croak "Error parsing formula" if not defined $parsed;
|
132
|
|
|
|
|
|
|
|
133
|
4
|
|
|
|
|
14
|
my $start = shift;
|
134
|
4
|
50
|
|
|
|
14
|
croak "A starting value must be supplied to Sequence->new() as second\n"
|
135
|
|
|
|
|
|
|
. "argument."
|
136
|
|
|
|
|
|
|
if not defined $start;
|
137
|
4
|
|
|
|
|
36
|
$start = $Parser->parse($start);
|
138
|
4
|
50
|
|
|
|
5471
|
croak "Error parsing starting value." if not defined $start;
|
139
|
|
|
|
|
|
|
|
140
|
4
|
|
|
|
|
11
|
my $variable = shift;
|
141
|
4
|
|
|
|
|
24
|
my @sig = $parsed->signature();
|
142
|
|
|
|
|
|
|
|
143
|
4
|
50
|
33
|
|
|
486
|
if ( @sig != 1 and not defined $variable ) {
|
144
|
0
|
|
|
|
|
0
|
croak "Formula must have one variable or a user defined\n"
|
145
|
|
|
|
|
|
|
. "variable must be supplied.";
|
146
|
|
|
|
|
|
|
}
|
147
|
4
|
100
|
|
|
|
20
|
$variable = $sig[0] if not defined $variable;
|
148
|
|
|
|
|
|
|
|
149
|
4
|
|
|
|
|
37
|
my $self = {
|
150
|
|
|
|
|
|
|
cached => 1,
|
151
|
|
|
|
|
|
|
var => $variable,
|
152
|
|
|
|
|
|
|
formula => $parsed,
|
153
|
|
|
|
|
|
|
current => 0,
|
154
|
|
|
|
|
|
|
current_value => $start,
|
155
|
|
|
|
|
|
|
cache => [$start],
|
156
|
|
|
|
|
|
|
};
|
157
|
4
|
|
|
|
|
34
|
return bless $self => $class;
|
158
|
|
|
|
|
|
|
}
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=item next()
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
The next() method returns the next element of the sequence and advances the
|
163
|
|
|
|
|
|
|
iterator by one. This is the prefered method of walking down a sequence's
|
164
|
|
|
|
|
|
|
recursion.
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=cut
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub next {
|
169
|
87
|
|
|
87
|
1
|
4487
|
my $self = shift;
|
170
|
87
|
|
|
|
|
149
|
my $current_index = $self->{current};
|
171
|
87
|
|
|
|
|
117
|
my $current_value = $self->{current_value};
|
172
|
87
|
|
|
|
|
197
|
my $next_index = $current_index + 1;
|
173
|
|
|
|
|
|
|
|
174
|
87
|
100
|
100
|
|
|
283
|
if ( $self->{cached} and defined $self->{cache}[$next_index] ) {
|
175
|
2
|
|
|
|
|
5
|
$self->{current_value} = $self->{cache}[$next_index];
|
176
|
2
|
|
|
|
|
5
|
$self->{current} = $next_index;
|
177
|
2
|
|
|
|
|
8
|
return $current_value;
|
178
|
|
|
|
|
|
|
}
|
179
|
|
|
|
|
|
|
|
180
|
85
|
|
|
|
|
338
|
my $next_value = $self->{formula}->new();
|
181
|
85
|
|
|
|
|
6103
|
$next_value->implement( $self->{var} => $current_value );
|
182
|
85
|
|
|
|
|
17446
|
$next_value = $next_value->simplify();
|
183
|
|
|
|
|
|
|
|
184
|
85
|
100
|
|
|
|
35311
|
$self->{cache}[$next_index] = $next_value if $self->{cached};
|
185
|
85
|
|
|
|
|
145
|
$self->{current} = $next_index;
|
186
|
85
|
|
|
|
|
114
|
$self->{current_value} = $next_value;
|
187
|
|
|
|
|
|
|
|
188
|
85
|
|
|
|
|
361
|
return $current_value;
|
189
|
|
|
|
|
|
|
}
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item cached()
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Returns a true value if the sequence is currently being cached, false if it
|
194
|
|
|
|
|
|
|
isn't. By default, new objects have caching enabled. It is suggested that you
|
195
|
|
|
|
|
|
|
only disable caching if space is an issue and you will only walk the sequence
|
196
|
|
|
|
|
|
|
uni-directionally and only once.
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
cached() can be used to change the caching behaviour. If the first argument is
|
199
|
|
|
|
|
|
|
true, caching will be enabled. If it is false, caching will be disabled.
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=cut
|
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub cached {
|
204
|
3
|
|
|
3
|
1
|
780
|
my $self = shift;
|
205
|
3
|
100
|
|
|
|
11
|
$self->{cached} = shift if @_;
|
206
|
3
|
|
|
|
|
20
|
return $self->{cached};
|
207
|
|
|
|
|
|
|
}
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item current_index()
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
Returns the index of the current element. That is, the index of the element
|
212
|
|
|
|
|
|
|
that will be returned by the next call to the next() method.
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
This method also allows (re-)setting the element that will be next returned by
|
215
|
|
|
|
|
|
|
the next() method. In that case, the first argument shoudl be the appropriate
|
216
|
|
|
|
|
|
|
index.
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Returns undef and doesn't set the current index if the argument is below 0.
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=cut
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub current_index {
|
223
|
44
|
|
|
44
|
1
|
17079
|
my $self = shift;
|
224
|
44
|
100
|
66
|
|
|
184
|
if ( @_ and defined $_[0] ) {
|
225
|
4
|
|
|
|
|
7
|
my $index = shift;
|
226
|
4
|
100
|
|
|
|
24
|
return undef if $index < 0;
|
227
|
2
|
|
|
|
|
7
|
$self->{current_value} = $self->at_index($index);
|
228
|
2
|
|
|
|
|
6
|
$self->{current} = $index;
|
229
|
2
|
|
|
|
|
12
|
return $index;
|
230
|
|
|
|
|
|
|
}
|
231
|
|
|
|
|
|
|
else {
|
232
|
40
|
|
|
|
|
162
|
return $self->{current};
|
233
|
|
|
|
|
|
|
}
|
234
|
|
|
|
|
|
|
}
|
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=item at_index()
|
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
This method returns the sequence element with the index denoted by the first
|
239
|
|
|
|
|
|
|
argument to the method. It does not change the state of the iterator.
|
240
|
|
|
|
|
|
|
This method is extremely slow for uncached sequences.
|
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
Returns undef for indices below 0.
|
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=cut
|
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
sub at_index {
|
247
|
20
|
|
|
20
|
1
|
3158
|
my $self = shift;
|
248
|
20
|
|
|
|
|
28
|
my $index = shift;
|
249
|
20
|
50
|
|
|
|
49
|
croak "Sequence->at_index() takes an index as argument."
|
250
|
|
|
|
|
|
|
if not defined $index;
|
251
|
20
|
100
|
|
|
|
53
|
return undef if $index < 0;
|
252
|
|
|
|
|
|
|
|
253
|
18
|
100
|
100
|
|
|
86
|
return $self->{cache}[$index]
|
254
|
|
|
|
|
|
|
if $self->{cached}
|
255
|
|
|
|
|
|
|
and defined $self->{cache}[$index];
|
256
|
|
|
|
|
|
|
|
257
|
15
|
100
|
|
|
|
39
|
if ( $self->{cached} ) {
|
258
|
1
|
50
|
|
|
|
2
|
if ( $index > $#{ $self->{cache} } ) {
|
|
1
|
|
|
|
|
6
|
|
259
|
1
|
|
|
|
|
3
|
my $old_index = $self->{current};
|
260
|
1
|
|
|
|
|
8
|
$self->next() for 1 .. $index - $self->{current};
|
261
|
1
|
|
|
|
|
5
|
my $value = $self->{current_value};
|
262
|
1
|
|
|
|
|
3
|
$self->{current} = $old_index;
|
263
|
1
|
|
|
|
|
4
|
$self->{current_value} = $self->{cache}[$old_index];
|
264
|
1
|
|
|
|
|
8
|
return $value;
|
265
|
|
|
|
|
|
|
}
|
266
|
|
|
|
|
|
|
else {
|
267
|
0
|
0
|
|
|
|
0
|
return $self->{cache}[$index]
|
268
|
|
|
|
|
|
|
if defined $self->{cache}[$index];
|
269
|
0
|
|
|
|
|
0
|
my $last_defined = $index;
|
270
|
0
|
|
0
|
|
|
0
|
while ( not defined $self->{cache}[$last_defined]
|
271
|
|
|
|
|
|
|
and $last_defined >= 0 )
|
272
|
|
|
|
|
|
|
{
|
273
|
0
|
|
|
|
|
0
|
$last_defined--;
|
274
|
|
|
|
|
|
|
}
|
275
|
0
|
0
|
|
|
|
0
|
die "Sanity check!" if $last_defined < 0;
|
276
|
0
|
|
|
|
|
0
|
my $old_index = $self->{current};
|
277
|
0
|
|
|
|
|
0
|
$self->{current} = $last_defined;
|
278
|
0
|
|
|
|
|
0
|
$self->{current_value} = $self->{cache}[$last_defined];
|
279
|
0
|
|
|
|
|
0
|
$self->next() for 1 .. $index - $last_defined;
|
280
|
0
|
|
|
|
|
0
|
my $value = $self->{current_value};
|
281
|
0
|
|
|
|
|
0
|
$self->{current} = $old_index;
|
282
|
0
|
|
|
|
|
0
|
$self->{current_value} = $self->{cache}[$old_index];
|
283
|
0
|
|
|
|
|
0
|
return $value;
|
284
|
|
|
|
|
|
|
}
|
285
|
|
|
|
|
|
|
}
|
286
|
|
|
|
|
|
|
else { # not $self->{cached}
|
287
|
14
|
50
|
|
|
|
36
|
return $self->{current_value} if $index == $self->{current};
|
288
|
14
|
|
|
|
|
21
|
my $old_index = $self->{current};
|
289
|
14
|
|
|
|
|
20
|
my $old_value = $self->{current_value};
|
290
|
14
|
|
|
|
|
15
|
my $value;
|
291
|
14
|
100
|
|
|
|
32
|
if ( $index < $self->{current} ) {
|
292
|
11
|
|
|
|
|
14
|
$self->{current} = 0;
|
293
|
11
|
|
|
|
|
25
|
$self->{current_value} = $self->{cache}[0];
|
294
|
11
|
|
|
|
|
79
|
$self->next() for 1 .. $index;
|
295
|
11
|
|
|
|
|
28
|
$value = $self->{current_value};
|
296
|
|
|
|
|
|
|
}
|
297
|
|
|
|
|
|
|
else {
|
298
|
3
|
|
|
|
|
13
|
$self->next() for 1 .. $index - $old_index;
|
299
|
3
|
|
|
|
|
10
|
$value = $self->{current_value};
|
300
|
|
|
|
|
|
|
}
|
301
|
14
|
|
|
|
|
23
|
$self->{current} = $old_index;
|
302
|
14
|
|
|
|
|
27
|
$self->{current_value} = $old_value;
|
303
|
14
|
|
|
|
|
43
|
return $value;
|
304
|
|
|
|
|
|
|
}
|
305
|
|
|
|
|
|
|
}
|
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=item back()
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
This methods returns the sequence element previously returned by the next()
|
310
|
|
|
|
|
|
|
method. Since it is extremely slow on uncached sequences, it warns about this
|
311
|
|
|
|
|
|
|
performance hit by default. To turn this warning off, set the
|
312
|
|
|
|
|
|
|
$Math::Sequence::warnings scalar to a false value.
|
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
This method decrements the current iterator sequence element.
|
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Returns undef if the current index goes below 0.
|
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=cut
|
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub back {
|
321
|
20
|
|
|
20
|
1
|
11119
|
my $self = shift;
|
322
|
20
|
|
|
|
|
34
|
my $current_index = $self->{current};
|
323
|
20
|
|
|
|
|
30
|
my $current_value = $self->{current_value};
|
324
|
20
|
|
|
|
|
29
|
my $prev_index = $current_index - 1;
|
325
|
20
|
50
|
|
|
|
48
|
return undef if $prev_index < 0;
|
326
|
|
|
|
|
|
|
|
327
|
20
|
50
|
66
|
|
|
65
|
carp "Use of the back() method on uncached sequence is not advised."
|
328
|
|
|
|
|
|
|
if ( not $self->{cached} )
|
329
|
|
|
|
|
|
|
and $Math::Sequence::warnings;
|
330
|
|
|
|
|
|
|
|
331
|
20
|
100
|
66
|
|
|
84
|
if ( $self->{cached} and defined $self->{cache}[$prev_index] ) {
|
332
|
10
|
|
|
|
|
22
|
$self->{current_value} = $self->{cache}[$prev_index];
|
333
|
10
|
|
|
|
|
12
|
$self->{current} = $prev_index;
|
334
|
10
|
|
|
|
|
42
|
return $self->{current_value};
|
335
|
|
|
|
|
|
|
}
|
336
|
|
|
|
|
|
|
|
337
|
10
|
|
|
|
|
28
|
my $prev_value = $self->at_index($prev_index);
|
338
|
10
|
|
|
|
|
16
|
$self->{current} = $prev_index;
|
339
|
10
|
|
|
|
|
11
|
$self->{current_value} = $prev_value;
|
340
|
|
|
|
|
|
|
|
341
|
10
|
|
|
|
|
42
|
return $prev_value;
|
342
|
|
|
|
|
|
|
}
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
1;
|
345
|
|
|
|
|
|
|
__END__
|