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


70

这似乎是一个非常简单的问题,但是我的Google-Fu使我失败了。

在Perl中包含其他文件中的函数的语法是什么?我正在寻找类似C的东西#include "blah.h"

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


8
Willy-nilly将脚本互相包含在一起令人痛苦。模块和脚本在代码方式上的区别非常微小,但是封装要好得多。您认为哪些特定的事情会使使用模块需要进行重大重写?
daotoad

3
我在网上看到的指南使创建和添加模块看起来比实际要复杂得多。感谢您向我展示其简单性
Zain Rizvi

Answers:


69

使用模块。perldoc perlmodExporter

在文件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 );

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



5
另外,如果您没有将模块安装在perl模块的默认位置之一,只需在“ use Foo;”之前添加它即可。行:使用lib('C:/ Module / Location');
Zain Rizvi

可以说我有默认位置的库,我想使用位于本地目录中的模块,因为它实际上仅由当前应用程序使用,并且创建该模块是为了更好地组织脚本。使用lib行会告诉perl只查看我为所有模块指定的位置,还是将其添加到perl搜索的lib路径中?
joejoeson 2010年


是否可以在整个主脚本以及您创建的模块中使变量全局化?如果是这样,在遇到麻烦时该怎么办?非常感谢
yonetpkbji 2013年

50

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则需要进行较早的编译时检查。

4
据我所知,这与C的#include更直接可比,而且正是我所需要的。
爱马仕(Herms)2010年

A package allows you to expose some functions, but hide others. With no packages, all functions are visible.我们如何做到这一点?
N3Xg3N 2014年



5

我知道这个问题专门说“函数”,但是当我寻找“ perl包含”时,我在搜索中的位置很高,而且经常(像现在这样)我想包含变量(以一种简单的方式,而不必考虑关于模块)。因此,我希望可以在此处发布我的示例(另请参见:Perl require和variables;简而言之:use require,并确保“ includer”和“ includee”文件都将变量声明为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脚本提供一组值的好方法吗?
iJames

4

您确实应该研究perl模块,但是,为了快速破解,您可以始终运行“ perl -P”,该程序通过C预处理器运行perl脚本。这意味着您可以做#include和朋友。

不过,请只小心一点;-)


4

您正在寻找的是“ require file.pl”,但您应该寻找的是“使用模块”。


3

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

请在此处查看已接受的答案: 如何从相对位置使用Perl模块?

没有这个答案的技巧,当您尝试正确获得模块路径时会遇到很多麻烦 use $mymodule;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.