[comp.lang.perl] Failure of "local" when "foreach" calls sub

dave@dlb.uucp (Dave Buck) (01/25/90)

OK, it looks like a bug to me.  I'm accepting opinions.
Below, test.4 calls a subroutine within a "foreach" loop.  Within the
subroutine, there is a "while" loop.  The local variables get
trounced upon completion of the "while", it seems.
Test.5 calls the same subroutine, but not from a "foreach".
The local variables don't get trounced.

RTFM'ing under "local(LIST)", "... this operator works by saving the current
values of those variables in LIST on a hidden stack and restoring them upon
exiting the block, subroutine or eval."  So I'm a thinkin' that someone gets
confused by that foreach block.  As I said, I'm accepting opinions.

Script started on Wed Jan 24 11:57:46 PST 1990
$ cat test.4
#!/usr/bin/perl -P -I/dave/projects
eval "exec /usr/bin/perl -P -I/dave/projects $0 $*"
	if $running_under_some_shell;

	foreach $dt (('5/1/87','11/1/87')) {
		$e_date = &mdy2epoch($dt);
	}

sub mdy2epoch {
	local ($mdy) = @_;
	local (@mdmax) = (0,31,28,31,30,31,30,31,31,30,31,30,31);
	local ($m,$d,$y,$e);
	($m,$d,$y) = split('/',$mdy);
print "mdy2epoch($mdy): $m $d $y\n";
	$y -= 1900 if ($y > 1900);
	$y -= 80;
print "y: $y ";
	$mdmax[2] = 29 if (($y%4) == 0);
	$e = $y * 365 + 1 + int(($y-1)/4);
print "e: $e  y: $y m: $m ";
	while (--$m) {
		$e += $mdmax[$m];
	}
print "m: $m  e: $e d: $d ";
	$e += $d;
print "return $e\n"; $e;
}
$ perl test.4
mdy2epoch(5/1/87): 5 1 87
y: 7 e: 2557  y: 7 m: 5 m:   e:  d:  return 0
mdy2epoch(11/1/87): 11 1 87
y: 7 e: 2557  y: 7 m: 11 m:   e: 0 d:  return 0
$ cat test.5
#!/usr/bin/perl -P -I/dave/projects
eval "exec /usr/bin/perl -P -I/dave/projects $0 $*"
	if $running_under_some_shell;

	$dt = '5/1/87';
	$e_date = &mdy2epoch($dt);

sub mdy2epoch {
	local ($mdy) = @_;
	local (@mdmax) = (0,31,28,31,30,31,30,31,31,30,31,30,31);
	local ($m,$d,$y,$e);
	($m,$d,$y) = split('/',$mdy);
print "mdy2epoch($mdy): $m $d $y\n";
	$y -= 1900 if ($y > 1900);
	$y -= 80;
print "y: $y ";
	$mdmax[2] = 29 if (($y%4) == 0);
	$e = $y * 365 + 1 + int(($y-1)/4);
print "e: $e  y: $y m: $m ";
	while (--$m) {
		$e += $mdmax[$m];
	}
print "m: $m  e: $e d: $d ";
	$e += $d;
print "return $e\n"; $e;
}
$ perl test.5
mdy2epoch(5/1/87): 5 1 87
y: 7 e: 2557  y: 7 m: 5 m: 0  e: 2677 d: 1 return 2678
$ Script done on Wed Jan 24 11:58:32 PST 1990
-- 
Dave Buck	{amdahl,sun,megatest,plx,ardent,ubvax}!dlb!dave
D. L. Buck and Associates, Inc.; San Jose, California 95119; (408)972-2825