perl 模块中的外部 conf 文件

External conf file in perl module

我是 Perl 的新手,需要这方面的建议。

我在“路径 1”中有一个脚本 Script.pl。 此外,我在“路径 2”中有一个模块 ModuleA.pm。 最后,我在“Path 3”中有一个公共模块ModuleB.pm。此 ModuleB 是通用的,其他路径中的其他脚本也使用它。 所有路径都是不同的。 Script.pl使用ModuleA,ModuleA使用ModuleB。

我需要在ModuleB中放一个外部配置文件。这个 conf 文件在同一个 "Path 3" 中。 conf.cfg 在 ModuleB 中是必需的:

use strict;
require "conf.cfg";

如何将 conf.cfg 作为动态方式包含在 ModuleB 中?因为如果我编译 Script.pl,则不会编译,因为找不到 conf.cfg ,因为现在 ModuleB 路径是 "Path 1" 而在 "Path 1" 中不存在 conf 文件。

所以我需要独立于 *.pl 和使用 ModuleB 的路径的 conf 文件。

我说的够清楚了吧?

提前致谢。

更新 添加代码以在运行时为 require 获取 ModuleB 路径,以避免对其进行硬编码,因为模块的位置可能会被移入更新(末尾的单独部分)。


在需要时为 conf.cfg 指定完整路径。

考虑以下层次结构和文件,其中所有路径都从 /path/

开始
/path/Path1/script.pl 
/path/Path2/ModuleA.pm 
/path/Path3/ModuleB.pm 
/path/Path3/conf.cfg

主要script.pl

use warnings;
use lib '/path';
use Path2::ModuleA;

文件Path2/ModuleA.pm

package ModuleA;    
use warnings;
use Path3::ModuleB;
1;

文件Path3/ModuleB.pm

package ModuleB;
use warnings;
require "Path3/conf.cfg";
1;

文件Path3/conf.cfg

use feature 'say';
say "This is conf.cfg";

运行 script.pl(从 Path1/ 内部)打印行 This is conf.cfg


注意行 use lib '/path',其中 /path 是一个文字字符串,指定 Path2Path3 开始的目录路径。参见 lib 杂注

It is typically used to add extra directories to perl's search path so that later use or require statements will find modules which are not located on perl's default search path.

可以更轻松地使用相对于脚本所在位置的库路径。在script.pl

# Load relative path for modules.
use FindBin qw($Bin);
use lib "$Bin/../lib";
use Path2::ModuleA;
# ...

在这种情况下 Path2(等)模块在目录 ../lib 中开始,相对于脚本所在的位置

./bin/script.pl
./lib/Path2/ModuleA.pm
./lib/Path3/...

我在这里选择了名字 bin 作为示例。查看核心模块FindBin.

这篇简短的笔记仅仅触及了如何组织模块的皮毛。


评论中出现了一个特定的约束。 ModuleB 所在的路径可能会随着未来的更新而改变,因此在 require 语句中对该路径进行硬编码并不是最佳选择。

一个解决方案是在运行时在 ModuleB 中找到路径并在 require 中使用该路径。这可以使用 Perl 的 special literal __FILE__.

来完成

文件Path3/ModuleB.pm

package ModuleB;

use warnings;
use strict;
use Cwd qw(abs_path);    

my ($this_dir) = abs_path(__FILE_) =~ m|(.*)/|;

require "$this_dir/conf.cfg";

1;

核心模块abs_path来自Cwd is needed since __FILE__ may not return the absolute path. The regex used to find the directory itself matches everything up to a / greedily, all the way up to the last / -- thus the whole path without the filename itself. Instead of doing that you can use functions from either of the File::Spec or File::Basename核心模块。