develooper Front page | perl.perl5.porters | Postings from March 2000

[ID 20000307.003] if(expr) and DESTROY

Thread Next
Matt Sergeant
March 7, 2000 05:29
[ID 20000307.003] if(expr) and DESTROY
Message ID:

This is a bug report for perl from,
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(@_);

$_ = '';

$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;


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

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(...);
  while(my $rec = $sth->fetchrow_arrayref) {
   # just want first row
   return $rec->[0];

sub fn2 {
 my $sth = $dbh->prepare(...);

if (fn1) {

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:
    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
    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:

Environment for perl 5.00503:
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PERL_BADLANG (unset)

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About