As an excersise in learning "tie", I knocked up this
series generator. I know this is probably not the ideal
solution to the problem of generating series, but it
was "tie" I was interested in.

I would very much apreciate your comments on my implementation.

Series.pm

`package Series;
use strict;
sub TIEARRAY {
my $pkg = shift;
my $rsub = shift; # sub for formula
my @vals = @_;
bless { 'values' => [ @vals ],
'next' => $rsub
}, $pkg;
}
sub FETCHSIZE {
# rather meaningless in context, but gets called a lot
# presume it's to check that any values at all exist
return 1; # for now
}
sub FETCH {
die "can't get subscripted value of series";
}
sub SHIFT {
my ($obj) = @_;
my $ra = $obj->{'values'};
push(@$ra, $obj->{'next'}->(@$ra));
return shift @$ra;
}
1;
`

series.pl

`#!/usr/bin/perl -w
use strict;
use Series;
print "Arithmetic Series: 1,4,7, ... N_{i-1}+3 ...\n";
tie my @arith, 'Series', sub { return 3 + shift }, 1;
print shift(@arith)." " for (1..15);
print "\n\n";
print "Geometric Series: 1,2,4, ... N_{i-1}*2 ...\n";
tie my @geo, 'Series', sub { return 2 * shift }, 1;
print shift(@geo)." " for (1..15);
print "\n\n";
print "Combination Series: 2,7,17, ... N_{i-1}*2+3 ...\n";
tie my @combo, 'Series', sub { return 3 + 2 * shift }, 2;
print shift(@combo)." " for (1..15);
print "\n\n";
print "Fibonacci Numbers: 0,1,1,2,3, ... N_{i-1}+N_{i-2} ...\n";
tie my @fibo, 'Series', sub { my @n = @_; return $n[0]+$n[1] }, 0,1;
print shift(@fibo)." " for (1..15);
print "\n";
`

And here is the output:

`Arithmetic Series: 1,4,7, ... N_{i-1}+3 ...
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43
Geometric Series: 1,2,4, ... N_{i-1}*2 ...
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
Combination Series: 2,7,17, ... N_{i-1}*2+3 ...
2 7 17 37 77 157 317 637 1277 2557 5117 10237 20477 40957 81917
Fibonacci Numbers: 0,1,1,2,3, ... N_{i-1}+N_{i-2} ...
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
`

--

Brother Marvell

**Edit**: chipmunk 2001-05-16