Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing on error message if AUTOLOAD fails

Tags:

perl

I am using AUTOLOAD to handle calls to some undefined subroutines.

sub AUTOLOAD {
    my $member = $AUTOLOAD;
    # ... do something if knowing how to handle '$member'        

    # otherwise ?
}

When calling a non-existent subroutine (say, my_method) on a package, Perl normally says something like

Can't locate object method "my_method" via package "MyPackage" 
at Package.pm line 99.

I want Perl to display this standard message in case I don't know how to handle the call to the subroutine $member in my implementation of AUTOLOAD.

How can I do that?

I found no special variable that might contain the appropriate message. Also the Perl documentation on Autoloading gives no hint for this problem.

Remark: I'd like to avoid rewriting the error message, but to use the standard message provided by Perl instead.

like image 403
Hermann Schachner Avatar asked Mar 18 '23 07:03

Hermann Schachner


2 Answers

No, the message isn't available anywhere. But you can use Carp to add the appropriate line and file:

sub AUTOLOAD {
    our $AUTOLOAD;
    my ($package,$method) = $AUTOLOAD=~/^(.*)::(.*)/s;
    use Carp ();
    local $Carp::CarpLevel = 1;
    Carp::croak( qq!Can't locate object method "$method" via package "$package"! );
}
like image 200
ysth Avatar answered Mar 19 '23 21:03

ysth


Unfortunately, you can't. Perl first attempts to locate a method within the package, then its parent packages in @ISA, and finally UNIVERSAL. Next it repeats that process but searches for AUTOLOAD in lieu of the method name. The only way perl is going to raise an exception at the point of invocation is if no method can be found. If perl has invoked your AUTOLOAD sub, it's already past the point of locating the method and it can only die from within AUTOLOAD's stack frame.

If you absolutely need to die where the method is invoked, your only option is to avoid AUTOLOAD and define all of your methods.

However, this will fake it, if only for the sake of appearance:

sub AUTOLOAD {
    my ($package, $method) = $AUTOLOAD =~ /^(.*)::([^:]*)/;
    die sprintf(qq{Can't locate object method "%s" via package "%s" at %s line %d.\n}, 
            $method, $package, (caller)[1,2]);
}
like image 23
Ben Grimm Avatar answered Mar 19 '23 21:03

Ben Grimm