从我使用Perl模块阅读的所有内容中,基本用法是:
.pm
扩展名的模块文件,其中包含语句package <name>
,其中<name>
是没有扩展名的模块的文件名。use <name>;
。我正在编码的应用程序有一个主代码脚本,它使用大约5个模块。我忘记在模块中包含package <name>
语句,但我的代码仍然可以使用use <name>
语句运行。我开始在其中一个模块中收到Undefined subroutine
错误,因此我将package语句添加到每个模块中。现在其余模块停止工作。是什么给了什么?
示例:的
mainapp.pl
#!/usr/bin/perl
use UtyDate;
my $rowDate = CurrentDate("YYYYMMDD");
UtyDate.pm
#!/usr/bin/perl
package UtyDate;
sub CurrentDate
{
#logic
}
return 1;
当我运行上面的代码时,我收到错误Undefined subroutine &main::CurrentDate called at...
。但是,如果我从UtyDate.pm中删除package UtyDate;
行,则不会出现错误。这种情况存在于几个但不是所有模块中。
显然有很多代码我没有展示,但我很困惑,我没有展示的任何代码可能会影响我在这里展示的包/使用结构。
答案 0 :(得分:10)
使用模块时,模块中的代码在编译时运行。然后在模块的包名称上调用import。因此,use Foo;
与BEGIN { require Foo; Foo->import; }
您的代码在没有package
声明的情况下工作,因为所有代码都是在主应用程序代码使用的包main
下执行的。
添加package
声明后,它停止工作,因为您定义的子程序不再在main
中定义,而是在UtyDate
中定义。
您可以使用完全限定名称UtyDate::CurrentDate();
访问子例程,也可以在use
模块时将子例程导入当前名称空间。
UtyDate.pm
package UtyDate;
use strict;
use warnings;
use Exporter 'import';
# Export these symbols by default. Should be empty!
our @EXPORT = ();
# List of symbols to export. Put whatever you want available here.
our @EXPORT_OK = qw( CurrentDate AnotherSub ThisOneToo );
sub CurrentDate {
return 'blah';
}
sub AnotherSub { return 'foo'; }
主程序:
#!/usr/bin/perl
use strict;
use warnings;
use UtyDate 'CurrentDate';
# CurrentDate is imported and usable.
print CurrentDate(), " CurrentDate worked\n";
# AnotherSub is not
eval { AnotherSub() } or print "AnotherSub didn't work: $@\n";
# But you can still access it by its fully qualified name
print UtyDate::AnotherSub(), " UtyDate::AnotherSub works though\n";
有关详细信息,请参阅Exporter文档。
答案 1 :(得分:3)
您缺少导出器perl标头代码。您需要在package语句下方的pm文件顶部添加以下内容:
package UtyDate;
BEGIN {
use Exporter ();
use vars qw($VERSION @ISA @EXPORT);
$VERSION = "1.0.0";
@ISA = qw(Exporter);
@EXPORT = qw( &CurrentDate );
}
答案 2 :(得分:1)
除了格雷的建议,你可以这样做:
use UtyDate;
UtyDate::CurrentDate(...);
答案 3 :(得分:0)
除了使用导出器之外,正如Gray指出的那样,你可以(UGLY,但也可以)使用模块名称调用函数。
您的函数/过程不起作用,因为它们现在位于不同的命名空间(由模块名称定义)
use UtyDate;
UtyDate::CurrentDate( )