new" ,你会得到这个众所周知的错误: Can't locate object method "new" via package "Bla" (perhaps -6ren">
gpt4 book ai didi

Perl 模块加载 - 防止 : perhaps you forgot to load "Bla"?

转载 作者:行者123 更新时间:2023-12-04 17:26:40 25 4
gpt4 key购买 nike

当你运行 perl -e "Bla->new" ,你会得到这个众所周知的错误:

Can't locate object method "new" via package "Bla"
(perhaps you forgot to load "Bla"?)
由于我的疏忽,前几天发生在 Perl 服务器进程中。有多个脚本,其中大多数都有正确的 use到位的声明。但是有一个脚本正在执行 Bla->newsub blub在第 123 行,但缺少 use 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;
});

关于Perl 模块加载 - 防止 : perhaps you forgot to load "Bla"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8031386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com