如果AUTOLOAD失败,则传递错误消息

时间:2015-01-21 15:34:56

标签: perl

我正在使用AUTOLOAD来处理对某些未定义子例程的调用。

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

    # otherwise ?
}

在包上调用不存在的子例程(比如my_method)时,Perl通常会说类似

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

我希望Perl显示此标准消息,以防我在$member的实现中不知道如何处理对子例程AUTOLOAD的调用。

我该怎么做?

我发现没有可能包含相应消息的特殊变量。 Perl documentation on Autoloading也没有提示这个问题。

备注:我想避免重写错误消息,而是使用Perl提供的标准消息。

2 个答案:

答案 0 :(得分:4)

不,该消息在任何地方都无法使用。但您可以使用Carp添加适当的行和文件:

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"! );
}

答案 1 :(得分:3)

不幸的是,你做不到。 Perl首先尝试在包中找到一个方法,然后在@ISA中找到它的父包,最后是UNIVERSAL。接下来,它会重复该过程,但会搜索AUTOLOAD来代替方法名称。 perl的唯一方法是在调用时引发异常,如果找不到方法的话。如果perl调用了你的AUTOLOAD sub,那么它已经超过定位方法的点,它只能从AUTOLOAD的堆栈帧中死掉。

如果您绝对需要在调用该方法,那么您唯一的选择就是避免AUTOLOAD并定义所有方法。

然而,如果只是出于外表的缘故,这会伪造它:

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]);
}
相关问题