【问题标题】:Does package compiled partially? How to prevent this?包是否部分编译?如何防止这种情况?
【发布时间】:2020-08-06 15:20:45
【问题描述】:

我有代码(删除了一些行):

package MaitreD::Command::bank_statement;
use Mojo::Base 'Mojolicious::Command';

sub run {
    ...
    my $payments =  read_file( $file );   # line 58
    ...
}

use XBase;                                # line 174
sub read_file {
    ...
}

1;

我运行我的应用程序。然后对这个应用程序执行两个 http 请求。控制器将此命令运行为:

$c->app->commands->run( bank_statement => $upload );

我得到下一个错误(这是预期的):

Can't locate XBase.pm in @INC (you may need to install the XBase module) (@INC contains: /opt/monkeyman/lib /opt/monkeyman/local/lib/perl5/x86_64-linux /opt/monkeyman/local/lib/perl5 /opt/monkeyman/lib /opt/monkeyman/local/lib/perl5/5.24.1/x86_64-linux /opt/monkeyman/local/lib/perl5/5.24.1 /opt/monkeyman/local/lib/perl5/x86_64-linux /opt/monkeyman/local/lib/perl5 /opt/perlbrew/perls/perl-5.24.1/lib/site_perl/5.24.1/x86_64-linux /opt/perlbrew/perls/perl-5.24.1/lib/site_perl/5.24.1 /opt/perlbrew/perls/perl-5.24.1/lib/5.24.1/x86_64-linux /opt/perlbrew/perls/perl-5.24.1/lib/5.24.1 .) at /opt/monkeyman/lib/MaitreD/Command/bank_statement.pm line 174.
BEGIN failed--compilation aborted at /opt/monkeyman/lib/MaitreD/Command/bank_statement.pm line 174.
Compilation failed in require at (eval 2620) line 1.

但是当我做第二个请求时,我得到了不同的错误:

Undefined subroutine &MaitreD::Command::bank_statement::read_file called at /opt/monkeyman/lib/MaitreD/Command/bank_statement.pm line 58.

如果模块MaitreD::Command::bank_statement 编译失败,如何从控制器运行MaitreD::Command::bank_statement::run

如果理解正确,模块MaitreD::Command::bank_statement 被部分编译为174 行。所以下一个对应用程序的http请求可以调用MaitreD::Command::bank_statement::run,当到达58行时,我得到Undefined subroutine &M::C::b::read_file called,因为在174行之后没有编译。

如何防止部分编译? 我想如果发生一些错误,那么MaitreD::Command::bank_statement 中的任何内容都应该不可用

【问题讨论】:

  • sub foo { ... } 等价于BEGIN { *foo = sub { ... } }。充其量,您可以在之后清理命名空间(删除包的内容)。

标签: perl


【解决方案1】:

看来您应该专注于确保 use XBase 真正成功,因为它的存在可能是有原因的,并且它是程序其余部分运行所必需的。

为什么会失败?先解决这个问题,部分编译就没有问题了。

既然如此,为什么perl找不到模块呢?

是否有可能 Command::bank_statement 类不是直接used,而只是在它运行时,所以当前工作目录可能在程序启动和调用$c->app->commands->run( bank_statement => $upload ); 之间发生了变化?

如果是这种情况,请尝试提前加载命令类。例如将此添加到 Mojo 应用程序类(可能类似于 lib/MaitreD.pm:

use MaitreD::Command::bank_statement;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-16
    • 2023-04-03
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多