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

问题描述 投票:0回答:10

这似乎是一个非常简单的问题,但不知怎的,我的 Google-Fu 让我失望了。

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

#include "blah.h"

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

perl include
10个回答
78
投票

使用模块。查看 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 );

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


55
投票

Perl require 可以完成这项工作。您需要通过添加

来确保任何“必需”文件返回真实值
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
    加载的包则受早期编译时检查的影响。

10
投票

此外,

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


8
投票

我相信您正在寻找 requireuse 关键字。


6
投票

我知道这个问题具体说的是“函数”,但是当我寻找“perl include”时,我在搜索中得到了这篇文章的高位,而且很多时候(就像现在)我想包含变量(以一种简单的方式,而不必考虑模块)。因此,我希望可以在这里发布我的示例(另请参阅:Perl require 和变量;简而言之:使用

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

4
投票

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

不过只是一个快速破解,请注意;-)


4
投票

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


3
投票

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

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

如果没有这个答案中的技巧,当你

use $mymodule;

时,你会在尝试正确获取模块路径时遇到很多麻烦

1
投票

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;

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

$string = trim($string);

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

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

package Foo;

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


0
投票

早在 2006 年,我就编写了一个名为 includelife 的 Perl 子例程。我以为你会感激的。今年我下载了 ChatGPT 3.5 并让该应用程序为子例程编写了白皮书。

sub includefile {
my $fname = shift;
my $file;

# Remove potentially harmful               
characters from the file name
$fname =~ s/([\&;\`'\|\"*\?\~\^\(\)\
[\]\{\}\$\n\r])//g;

# Open the file for reading
if (!fopen(INCLUDE, $fname)) {
    return '[an error occurred while processing this directive]';
}

# Read the content of the file and 
store it in $file
$file = join('', <INCLUDE>);

# Close the file
fclose(INCLUDE);

return $file;

}

© www.soinside.com 2019 - 2024. All rights reserved.