Front page | perl.perl5.porters |
Postings from March 2000
[ID 20000307.003] if(expr) and DESTROY
Thread Next
From:
Matt Sergeant
Date:
March 7, 2000 05:29
Subject:
[ID 20000307.003] if(expr) and DESTROY
Message ID:
200003071330.NAA08245@dougal.sergeant.org
This is a bug report for perl from matt@sergeant.org,
generated with the help of perlbug 1.26 running under perl 5.00503.
-----------------------------------------------------------------
[Please enter your report here]
Thanks to tomC for helping debug this one...
DESTROY isn't called until the end of an if{} block.
Witness (thanks to tom for the script):
#!/usr/bin/perl -l
package Ob;
sub DESTROY { print "DESTROY $_[0] <$_[0]->{ID}" }
sub alloc {
my ($class, $id) = (@_, scalar localtime);
my $self = bless { ID => $id };
print "ALLOC $self >$id";
return $self;
}
package main;
sub INIT { print "...RUNNING...\n" }
sub END { print "\n...CLEANUP..." }
sub fn {
my $ob = Ob->alloc(@_);
1;
}
$_ = '';
$fred = Ob->alloc("Fred");
print "\nif test\n";
if (fn("Outer if")) {
fn("Inner if");
}
print "\n&& test\n";
fn("Outer &&") && fn("Inner &&");
print "\nwhile test\n";
$i = 0;
while (fn("Outer $i")) {
fn("Inner $i");
last if $i++ > 4;
}
exit;
__END__
...RUNNING...
ALLOC Ob=HASH(0x9e150) >Fred
if test
ALLOC Ob=HASH(0x9e060) >Outer if
ALLOC Ob=HASH(0xa77cc) >Inner if
DESTROY Ob=HASH(0xa77cc) <Inner if
DESTROY Ob=HASH(0x9e060) <Outer if
&& test
ALLOC Ob=HASH(0xa9c3c) >Outer &&
ALLOC Ob=HASH(0xa77cc) >Inner &&
DESTROY Ob=HASH(0xa77cc) <Inner &&
DESTROY Ob=HASH(0xa9c3c) <Outer &&
while test
ALLOC Ob=HASH(0xa9c0c) >Outer 0
DESTROY Ob=HASH(0xa9c0c) <Outer 0
ALLOC Ob=HASH(0x9e060) >Inner 0
DESTROY Ob=HASH(0x9e060) <Inner 0
ALLOC Ob=HASH(0x9e060) >Outer 1
DESTROY Ob=HASH(0x9e060) <Outer 1
ALLOC Ob=HASH(0xa9c3c) >Inner 1
DESTROY Ob=HASH(0xa9c3c) <Inner 1
ALLOC Ob=HASH(0xa9c3c) >Outer 2
DESTROY Ob=HASH(0xa9c3c) <Outer 2
ALLOC Ob=HASH(0xa9c0c) >Inner 2
DESTROY Ob=HASH(0xa9c0c) <Inner 2
ALLOC Ob=HASH(0xa9c0c) >Outer 3
DESTROY Ob=HASH(0xa9c0c) <Outer 3
ALLOC Ob=HASH(0x9e060) >Inner 3
DESTROY Ob=HASH(0x9e060) <Inner 3
ALLOC Ob=HASH(0x9e060) >Outer 4
DESTROY Ob=HASH(0x9e060) <Outer 4
ALLOC Ob=HASH(0xa9c3c) >Inner 4
DESTROY Ob=HASH(0xa9c3c) <Inner 4
ALLOC Ob=HASH(0xa9c3c) >Outer 5
DESTROY Ob=HASH(0xa9c3c) <Outer 5
ALLOC Ob=HASH(0xa9c0c) >Inner 5
DESTROY Ob=HASH(0xa9c0c) <Inner 5
...CLEANUP...
DESTROY Ob=HASH(0x9e150) <Fred
In both the if() and the && case, DESTROY is called later than it should be.
It should be called on exit of the function, as per the scoping rules. The
while loop does the right thing, strangely enough.
This bit me when trying to do this with DBD::Sybase:
sub fn1 {
my $sth = $dbh->prepare(...);
$sth->execute;
while(my $rec = $sth->fetchrow_arrayref) {
# just want first row
return $rec->[0];
}
}
sub fn2 {
my $sth = $dbh->prepare(...);
$sth->execute;
}
if (fn1) {
fn2;
}
This bites you because the TDS protocol doesn't allow more than one active
statement on a single connection when using transactions. A work around
is to undef the $sth in the while loop before returning.
[Please do not change anything below this line]
-----------------------------------------------------------------
---
This perlbug was built using Perl 5.00503 - Tue Apr 13 04:04:31 CEST 1999
It is being executed now by Perl 5.00557 - Fri Jul 16 22:00:43 /etc/localtime 1999.
Site configuration information for perl 5.00503:
Configured by root at Tue Apr 13 04:04:31 CEST 1999.
Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
Platform:
osname=linux, osvers=2.2.5-4, archname=i386-linux
uname='linux vador 2.2.5-4 #1 tue apr 6 19:46:00 edt 1999 i686 unknown '
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef useperlio=undef d_sfio=undef
Compiler:
cc='cc', optimize='-O2', gccversion=pgcc-2.91.60 19981201 (egcs-1.1.1 release)
cppflags='-Dbool=char -DHAS_BOOL -I/usr/local/include'
ccflags ='-Dbool=char -DHAS_BOOL -I/usr/local/include'
stdchar='char', d_stdstdio=undef, usevfork=false
intsize=4, longsize=4, ptrsize=4, doublesize=8
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
alignbytes=4, usemymalloc=n, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt
libc=, so=so, useshrplib=false, libperl=libperl.a
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'
Locally applied patches:
---
@INC for perl 5.00503:
/usr/lib/perl5/5.00503/i386-linux
/usr/lib/perl5/5.00503
/usr/lib/perl5/site_perl/5.005/i386-linux
/usr/lib/perl5/site_perl/5.005
.
---
Environment for perl 5.00503:
HOME=/home/matt
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/usr/local/bin:/bin:/usr/bin::/usr/X11R6/bin:/var/qmail/bin:/usr/local/sbin:/usr/local/jdk1.2/bin:/opt/sybase/bin:/home/matt/bin:/usr/local/jdk1.2/bin:/opt/sybase/bin
PERL_BADLANG (unset)
SHELL=/bin/bash
Thread Next
-
[ID 20000307.003] if(expr) and DESTROY
by Matt Sergeant