如何在 Perl 脚本中包含来自另一个文件的函数?

这似乎是一个非常简单的问题,但不知何故,我的谷歌福音失败了。

在 Perl 中包含来自其他文件的函数的语法是什么

我看到了使用 Perl 模块的选项,但是这似乎需要对我当前的代码进行重写。

98094 次浏览

我相信你正在寻找的 要求使用关键字。

不过,您确实应该研究一下 perl 模块,为了快速获得技巧,您总是可以运行“ perl-P”,它通过 C 预处理器运行您的 perl 脚本。这意味着你可以做 # 包括和朋友... 。

不过,只是一个快速的黑客,当心; -)

Perl要求将完成这项工作。您将需要确保任何“需要的”文件通过添加

1;

在文件的末尾。

这里有一个小样本:

$ cat m1.pl
use strict;
sub x { warn "aard"; }
1;


$ cat m2.pl
use strict;
require "m1.pl";
x();


$ perl m2.pl
aard at m1.pl line 2.

但是迁移到模块 尽快

剪辑

将代码从脚本迁移到模块的一些好处:

  • 如果没有包,则所有内容都占用一个名称空间,因此可能会遇到来自不同文件的两个函数需要相同名称的情况。
  • 一个包允许你公开一些函数,但是隐藏其他的。如果没有包,所有的函数都是可见的。
  • 包含在 require中的文件只在运行时加载,而包含在 use中的包需要进行早期的编译时检查。

使用模块。检查 Perldoc Perlmod出口商

在 Foo.pm 文件中

package Foo;
use strict;
use warnings;
use Exporter;


our @ISA= qw( Exporter );


# these CAN be exported.
our @EXPORT_OK = qw( export_me export_me_too );


# these are exported by default.
our @EXPORT = qw( export_me );


sub export_me {
# stuff
}


sub export_me_too {
# stuff
}


1;

在你的主程序中:

use strict;
use warnings;


use Foo;  # import default list of items.


export_me( 1 );

或者得到两个函数:

use strict;
use warnings;


use Foo qw( export_me export_me_too );  # import listed items


export_me( 1 );
export_me_too( 1 );

您也可以导入包变量,但是强烈建议不要这样做。

您要查找的是“ need file.pl”,但是应该查找的是“ use module”。

此外,do 'file.pl';也可以工作,但模块是更好的解决方案。

我知道这个问题特别提到了“函数”,但是当我在搜索“ perl include”时,我会把这篇文章放在很高的位置,而且通常(比如现在)我想要包含变量(用一种简单的方式,不需要考虑模块)。因此,我希望在这里发布我的示例没有问题(另见: Perl request 和变量; 简而言之: 使用 require,并确保“ include er”和“ include dee”文件都将变量声明为 our) :

$ perl --version


This is perl, v5.10.1 (*) built for i686-linux-gnu-thread-multi ...


$ cat inc.pl
use warnings;
use strict;


our $xxx = "Testing";


1;


$ cat testA.pl
use warnings;
use strict;


require "inc.pl";
our $xxx;


print "1-$xxx-\n";
print "Done\n";


$ perl testA.pl
1-Testing-
Done




$ cat testB.pl
use warnings;
use strict;


our $xxx;
print "1-$xxx-\n";


$xxx="Z";
print "2-$xxx-\n";


require "inc.pl";


print "3-$xxx-\n";
print "Done\n";


$ perl testB.pl
Use of uninitialized value $xxx in concatenation (.) or string at testB.pl line 5.
1--
2-Z-
3-Testing-
Done

上面的答案都忽略了客户端部分: 如何导入模块。

在这里可以看到公认的答案: 如何从相对位置使用 Perl 模块?

如果没有这个答案中的技巧,那么在 use $mymodule;中尝试获得正确的模块路径将会遇到很多麻烦

require大致相当于包括。所有的名称空间优势都可以在一个所需的 perl 脚本中实现,就像 perl 模块一样。“魔力”在于你在剧本里写了什么。

包含脚本的唯一警告是您需要在脚本的末尾使用 return 1;,否则 perl 会说它失败了,即使您没有在脚本中调用任何内容。

require "./trims.pl"

然后在 perl 脚本中,它可以简单如下:

#!/usr/bin/perl


#use "trims.pl";




sub ltrim { my $s = shift; $s =~ s/^\s+//;       return $s };
sub rtrim { my $s = shift; $s =~ s/\s+$//;       return $s };
sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
return 1;

此示例从输入字符串的左端、右端或两端删除空白

#use "trims.pl"的注释可以粘贴到 perl 脚本中,取消注释(删除 #) ,perl 会在脚本所在的同一个文件夹中查找 trims.pl,这会将函数 lrim ()、 rrim ()和 trim ()放在全局名称空间中,因此不能将这些函数名放在任何其他全局名称空间中,否则 perl 会检测到冲突并停止执行。

要了解有关控制名称空间的更多信息,请查看“ perl 软件包和模块”package Foo;

Https://perldoc.perl.org/functions/package