I'm having a problem with error handling in an AUTOLOAD subroutine. Here's a (very) simplified version of the code that exhibits the bad behaviour plus a work around:

#!/usr/bin/perl -w
use strict;

package Bob;

sub AUTOLOAD {
our %AUTOLOADED;
our $AUTOLOAD;
print 'Autoloading ', $AUTOLOAD, "\n";
no strict "refs";
if (not exists $AUTOLOADED{$AUTOLOAD}) {
$AUTOLOADED{$AUTOLOAD} = 1; # check it myself
goto &$AUTOLOAD if (*{$AUTOLOAD}{CODE});
}
'<br />Internal Error: Call to undefined subroutine "' . $AUTOLOAD . '"<br />';
}


sub test {
    1;
}

package main;

print "Start\n";
my $fptr;
{
    no strict "refs";
    my $name = "Bob::nop";
    print "Capturing name\n";
    $fptr = \&$name;
}
print "Calling test\n";
print &Bob::test(), "\n";
print "Calling none\n";
print &Bob::none(), "\n";
print "Calling nop\n";
print &Bob::nop(), "\n";

If you run this, it will run cleanly but one should note that "Autoloading" is printed twice after "Calling nop" indicating that the AUTOLOAD subroutine re-entered. If you comment out the line marked "check it myself" then running this script will completely lock up the PERL executable (it's so virulent that I crashed a webhost with it - the load average went from ~4 to over 200 in a matter of seconds. How a non-threaded perl script managed to push the load average up more than 1 I don't understand, but there you are).

The problem is that when the name 'Bob::nop' is "captured", some kind of CODE object is put in that symbol, even though it's not defined in the Bob package. The capturing is an artifact of a registration system where strings in text to be processed are identified with PERL subroutines to run so I can't avoid that. The goal would be to catch cases where the targeted PERL subroutine doesn't exist without having to explicitly load all of the packages.

Yet that renders me unable to check to see if the subroutine is really in the package. As far as I can tell, doing my own check is the only way to do this safely. Has anyone else seen this? Is it a known, common problem? I've done some searching but can't find any mention of it (although I may have just missed it in the noise).

I suppose the best solution is to tweak the registration to keep the string and when it is actually invoked, extract the package, do the 'require' and capture at that point. Still, this seems like odd behaviour.

Run on Windows XP, ActiveState PERL 5.8.4 build 810.

_______________________________________________
ActivePerl mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to