【问题标题】:Using module in the same directory. "Undefined subroutine called at"使用同一目录中的模块。 “未定义的子程序调用于”
【发布时间】:2017-10-30 15:24:11
【问题描述】:

我有 test_utils.pm

package TestUtils;
use strict;
use warnings;

use Exporter 'import';
our @EXPORT = qw / print_diagnostic /;

sub print_diagnostic { <some_code_here> }

我想从位于同一文件夹中的主脚本 tester.pl 调用print_diagnostic(我使用过this solution):

#!/usr/bin/perl
use lib dirname (__FILE__);
use test_utils qw (:ALL);

print_diagnostic(<some_message>);

问题是我得到了

未定义的子例程 &main::print_diagnostic 在...调用

使用显式包名 TestUtils::print_diagnostic 调用函数可以正常工作,但由于各种原因,我确实想在不带这样前缀的情况下调用它。

use test_utils qw(print_diagnostic);

require test_utils;

产生相同的结果。

我已经挖掘了几十个类似的问题,尝试了答案和“解决方案”,但所有这些似乎都对我不起作用,而且我对所有“导出”、“导入”感到非常困惑" 以及它周围的所有东西,我无法抓住这些概念,如此违反直觉,比较 C++ 和 Java。

我想做的就是将非常复杂的脚本拆分成几个模块并重用代码(现在有很多重复)。

【问题讨论】:

    标签: perl perl-module perl-exporter


    【解决方案1】:
    use test_utils qw( :ALL );
    

    等价于

    BEGIN {
       require test_utils;
       import test_utils qw( :ALL );
    }
    

    但你想要

    BEGIN {
       require test_utils;
       import TestUtils qw( :ALL );
    }
    

    为文件和包使用相同的名称以避免此问题。


    顺便说一句,你应该替换

    use File::Basename qw( dirname );
    use lib dirname(__FILE__);
    

    use Cwd qw( abs_path );
    use File::Basename qw( dirname );
    use lib dirname(abs_path(__FILE__));
    

    或者干脆

    use FindBin qw( $RealBin );
    use lib $RealBin;
    

    如果使用脚本的符号链接,您的版本将中断。

    【讨论】:

    • 请不要使用间接宾语表示法。 import Foo $bar 最好写成Foo-&gt;import($bar)
    • @melpomene, import 被记录为运算符,它不像其他方法调用那样工作。 (如果该方法不存在,它不会失败。)我没有看到你到处告诉人们不要使用print STDERR ...;
    • @ikegami,非常感谢!这澄清了我头脑中的所有混乱)
    • @ikegami 不同之处在于print 是一个(内置)运算符,而import 只是一个子程序:perl -we 'sub import; import Foo' 执行普通函数调用,import(Foo)。你说得对,import 是一个特殊的方法(如果找不到该方法,调用它不会失败),但它只是一个用户定义的方法。
    • @amon,正如我已经提到的,您引用的段落(“这只是一种普通的方法”)显然是错误的。 (例如perl -e'__PACKAGE__-&gt;import; __PACKAGE__-&gt;importx'import 非常神奇,应该让读者明白这一点。您声称import 是从UNIVERSAL 继承的,这是错误的。 (例如perl -E'say for keys %UNIVERSAL::'。)在我看来,我使用的是import 运算符,它可能会调用import 方法。
    猜你喜欢
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 2015-02-06
    相关资源
    最近更新 更多