Lhamo Latso has asked for the wisdom of the Perl Monks concerning the following question:

This seems to be a filehandle issue. I am using IO::File to access 5 static HTML files, in order to build a web page. I have used this technique before with one file, but something goes wrong when I reuse the variable holding the filehandle. Everything executes fine, but I get errors during cleanup.

Here is a code fragment:

use IO::File (); local $/; foreach (sort keys %altnames) { my $fh = IO::File->new; my ($hr_title) = m/(.*)\.txt/; print("<hr> <h1 align=center> $hr_title </h1>\n"); my $source = join '/', $dir, $_; $fh->open($source); while (<$fh>) { print($_); } $fh->close; }

I have found that I get the error even for one loop. I inserted "last;" just after the close to test.

If I comment the print($_) statement, I still get the error.

If I comment the "while (<$fh>)" loop entirely, the errors go away!!

Here is the error log:

Unbalanced string table refcount: (1) for "Oracle.txt" during global destruction.

Unbalanced string table refcount: (1) for "Administration.txt" during global destruction.

Unbalanced string table refcount: (1) for "Perl.txt" during global destruction.

Unbalanced string table refcount: (1) for "Java.txt" during global destruction.

Unbalanced string table refcount: (1) for "Web Development.txt" during global destruction.
Thanks for any help!

Edited 2003-03-19 by mirod: replaced pre tags by code tags

Replies are listed 'Best First'.
Re: Unbalance string table refcount
by graff (Chancellor) on Mar 19, 2003 at 02:19 UTC
    Consider the following:
    use IO::File (); ## local $/; # you're not using this my $fh = IO::File->new(); # declare this just once foreach $file (sort keys %altnames) { my ($hr_title) = ( $file =~ m/(.*)\.txt/ ); print "<hr> <h1 align=center> $hr_title </h1>\n"; # don't need parens for print ... $fh->open( "$dir/$file" ) or die $!; # you gotta check! while (<$fh>) { print; } $fh->close; }
    I think that having only one instance of IO::File will help (but I haven't tested this). Also, having something besides $_ as the "foreach" loop variable could make a difference, since you are also using $_ to iterate in the "while" loop, which might cause unexpected consequences (e.g. changing the strings that are used as the keys in %altnames).

    update: I rigged up five dummy files with names as indicated in your error messages, and tested your original code with perl 5.8.0 on linux SuSE 7.3 -- didn't get any errors, so I'm at a loss. The comment about altering the hash key strings in the while loop was misguided; still, it seems better to have the outer loop using an iterator variable that's different from the inner loop. Anyway, my version ran as well (after I fixed a missing dash character in the "IO::File->new()" line).

      Thanks so much.

      The thing that fixed the error appears to be using 2 levels of $_. I changed it to "foreach my $file (sort ... and the errors are gone.

Re: Unbalance string table refcount
by pg (Canon) on Mar 19, 2003 at 03:15 UTC
    This is definitely something you should not see. It is a bug. As you didn't indicate your perl version, I cannot say whether it is worth to report as a bug. If it is 5.8, definitely report it.

    For the time beging, you can set environment variable PERL_DESTRUCT_LEVEL to 2, see whether it works, usually it does. If not, play with even lower values.

    BTW, just in case, this sounds like a good oppotunity for using things like CGI, HTML::Template etc. Did you use those? Update:

    Lhamo Latso, I saw your reply to graff, but this is still a Perl bug. Regardless how you use it, Perl destruction process itself should work gracefully. If you are using 5.8, I suggest you to keep a version of your "bad" code, and report this bug.
      This is version 5.8.0 on RedHat 8.0.

      Actually, I am inside of ModPerl with this code. I have used CGI.pm before, but for this one it seems to be too much overhead. I am assembling this semi-static web page from multiple sources.

      Thanks. I will report the bug.