加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl模块加载 – 防止:也许你忘了加载“Bla”?

发布时间:2020-12-15 21:46:45 所属栏目:大数据 来源:网络整理
导读:当你运行perl -e“Bla- new”时,你会得到这个众所周知的错误: Can't locate object method "new" via package "Bla"(perhaps you forgot to load "Bla"?) 由于我的疏忽,前几天发生在Perl服务器进程中.有多个脚本,其中大多数都有适当的使用语句.但是有一个脚
当你运行perl -e“Bla-> new”时,你会得到这个众所周知的错误:
Can't locate object method "new" via package "Bla"
(perhaps you forgot to load "Bla"?)

由于我的疏忽,前几天发生在Perl服务器进程中.有多个脚本,其中大多数都有适当的使用语句.但是有一个脚本在第123行在sub blub中做Bla-> new但在顶部缺少一个使用Bla,当它被点击而没有使用Bla的任何其他脚本被服务器加载时过程之前,然后爆炸!

单独测试脚本将是防止这一特定错误的明显方法,但唉,代码依赖于一个巨大的环境.你知道另一种防止这种疏忽的方法吗?

更新

以下是PPI(尽管它的优点)在Perl视图中受到限制的一个例子:

use strict;
use HTTP::Request::Common;

my $req = GET 'http://www.example.com';
$req->headers->push_header( Bla => time );

my $au=Auweia->new;

__END__
PPI::Token::Symbol          '$req'
PPI::Token::Operator        '->'
PPI::Token::Word            'headers'
PPI::Token::Operator        '->'
PPI::Token::Word            'push_header'

PPI::Token::Symbol          '$au'
PPI::Token::Operator        '='
PPI::Token::Word            'Auweia'
PPI::Token::Operator        '->'
PPI::Token::Word            'new'

设置标题并分配Auweia-> new解析相同.所以我不确定你如何在这样一个摇摇欲坠的基础上建立起来.我认为问题在于Auweia也可能是一个子程序; perl.exe直到运行时才能分辨.

进一步更新

好的,从@ Schwern的下面的指导性评论我了解到PPI只是一个标记器,如果你接受它的局限性,你可以在它上面构建.

解决方法

测试是唯一值得付出努力的答案.如果代码包含忘记加载类的错误,则可能包含其他错误.无论遇到什么障碍,都要考验一下.否则你正在修补一个筛子.

也就是说,你有两种选择.您可以使用Class::Autouse,如果模块尚未加载,将尝试加载模块.它很方便,但因为它会影响整个过程,所以会产生意想不到的影响.

或者您可以使用PPI扫描代码并查找所有类方法调用. PPI::Dumper非常方便了解PPI如何看待Perl.

use strict;
use warnings;

use PPI;
use PPI::Dumper;

my $file = shift;
my $doc = PPI::Document->new($file);

# How PPI sees a class method call.
#    PPI::Token::Word      'Class'
#    PPI::Token::Operator  '->'
#    PPI::Token::Word      'method'
$doc->find( sub {
    my($node,$class) = @_;

    # First we want a word
    return 0 unless $class->isa("PPI::Token::Word");

    # It's not a class,it's actually a method call.
    return 0 if $class->method_call;

    my $class_name = $class->literal;

    # Next to it is a -> operator
    my $op = $class->snext_sibling or return 0;
    return 0 unless $op->isa("PPI::Token::Operator") and $op->content eq '->';

    # And then another word which PPI identifies as a method call.
    my $method = $op->snext_sibling or return 0;
    return 0 unless $method->isa("PPI::Token::Word") and $method->method_call;

    my $method_name = $method->literal;

    printf "$class->$method_name seen at %s line %d.n",$file,$class->line_number;
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读