【问题标题】:Not able to export methods using Exporter module in perl无法在 perl 中使用 Exporter 模块导出方法
【发布时间】:2017-10-07 17:37:49
【问题描述】:

我正在尝试使用Exporter perl 模块导出在我的自定义模块中编写的方法。下面是我的自定义模块ops.pm

use strict;
use warnings;
use Exporter;

package ops;
our @ISA= qw/Exporter/;

our @EXPORT=qw/add/;

our @EXPORT_OK=qw/mutliply/;

sub new
{
        my $class=shift;
        my $self={};
        bless($self,$class);
        return $self;
}


sub add
{
        my $self=shift;
        my $num1=shift;
        my $num2=shift;
        return $num1+$num2;
}

sub mutliply
{
        my $self=shift;
        my $num1=shift;
        my $num2=shift;
        return $num1*$num2;
}

1;

下面是使用ops.pm的脚本ops_export.pl

#!/usr/bin/perl

use strict;
use warnings;
use ops;


my $num=add(1,2);
print "$num\n";

当我执行上面的脚本时,我遇到了错误。

Undefined subroutine &main::add called at ops_export.pl line 8.

我不明白为什么我的脚本会签入 &main 包,即使我使用 @EXPORT 导出了 ops.pm 中的 add

我哪里错了?

【问题讨论】:

  • ops 是 Perl 已经使用的编译指示:perldoc.perl.org/ops.html 使用不同的名称。
  • 另请注意,所有小写名称仅用于编译指示。为您自己的模块使用驼峰式名称(如Ops)。而且您已经混淆了面向对象的代码和常规函数。即使导入有效,您的代码也会失败,因为您正在调用函数之类的方法。在你打电话给add 时,$self 不见了。
  • 您应该没有理由导出方法。只能通过该类的对象调用它们。

标签: perl perl-module


【解决方案1】:

ops 是一个编译指示 already used by Perl。来自文档:

ops - 编译时限制不安全操作的 Perl 编译指示

我不知道这实际上意味着什么,但这就是这里的问题。

将您的模块重命名为其他名称,最好是@simbabque 在评论中建议的带有大写字符的名称,因为小写“模块”以某种方式保留用于编译指示(想想warningsstrict)。

另外:调用 add 函数将不起作用,因为您混淆了 OO 代码和常规函数。您的add 需要三个参数,而您只提供两个(12)。

在编写 OO 模块时,您不应导出任何内容(甚至 new),即:

package Oops;
use strict; use warnings;
use OtherModules;
# don't mention 'Export' at all
sub new {
    ...
}
sub add {
    ...
}
1;

然后在你的脚本中:

use strict; use warnings;
use Oops;
my $calculator = Oops->new();
my $result = $calculator->add(1, 2);
print $result, "\n"; # gives 3

【讨论】:

  • 自定义ops.pm 文件的位置也很有趣。如果它位于@INC 前面的目录中,它可能会起作用,但可能会导致各种其他问题。
猜你喜欢
  • 2023-03-14
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-26
  • 2021-01-22
  • 2020-05-07
相关资源
最近更新 更多