Perl - 模块内文件的相对路径

标签 perl relative-path perl-module

我正在使用 Perl 建立一个网站。我按如下方式组织我的文件:

  • /index.cgi
  • /perl/modules/databaseFunctions.pm
  • /perl/indexCheck.cgi
  • /database/database.xml

databaseFunctions.pm内部,我有一个函数X(),可以在database.xml上读取和写入。在 X() 中,我指定了数据库的相对路径,如下所示:

sub X{
    my $db_path='../../database/database.xml';
    my $parser=XML::LibXML->new();
    my $doc=$parser->parse_file($db_path);
    ....
    ....
 }

问题是这样的:
我必须从index.cgi 和indexCheck.cgi 调用X(),但出现以下错误:

Could not create file parser context for file "../../database/database.xml": No such file or directory at perl/modules/databaseFunctions.pm line 21.

我认为问题是,当我在index.cgi或/perl/indexCheck.cgi内部调用X()时,数据库的相对路径是不同的,但我不知道如何设置适用于索引的路径.cgi 和/perl/indexCheck.cgi。

最佳答案

我认为问题归结为“如何找出当前脚本(*.pl)的路径?”和 “如何找到当前模块(*.pm)的路径?”。

脚本

对于脚本来说,有一个非常方便的模块, FindBin ,为当前脚本的名称和路径提供 4 个变量 符号链接(symbolic link)是否已解析。通常$FindBin::Bin就是您正在寻找的。这是当前脚本的路径。 我经常用它来增强@INC路径,以便我的脚本找到其他(自己的)模块,如下所示:

use FindBin;
use lib "$FindBin::Bin/my_mod_path";
use MyModule;

在本例中MyModule.pm在目录 my_mod_path 中搜索在当前脚本路径下方。非常方便。

该模块是核心发行版的一部分,即无需进一步安装。

模块

FindBin可能无法从模块内部安全地使用,因为这取决于谁(脚本或模块)创建了第一个 use FindBin; 。 所以如果你不想关心顺序,就不要use FindBin;在模块中,仅在脚本中。

对于模块,有一些技巧。使用perl函数 caller() 。 根据调用的上下文,它返回 $filename实际调用它的文件的位置。

因此,在模块中,您可以安全地使用以下内容来获取模块的路径:

use File::Basename;
my $path_of_this_module = File::Basename::dirname( eval { ( caller() )[1] } );

给定该路径,您可以相对于它进行导航,以找到您需要的其他文件,例如"$path_of_this_module/../.."等等。

编辑

索引.cgi:

#!/usr/bin/env perl

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/perl/modules";
use databaseFunctions;

databaseFunctions::X( "called from index.cgi\n" );

perl/indexCheck.cgi:

#!/usr/bin/env perl

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/modules";
use databaseFunctions;

databaseFunctions::X( "called from indexCheck.cgi\n" );

perl/modules/databaseFunctions.pm:

package databaseFunctions;

use File::Basename;

my $path_of_this_module = File::Basename::dirname( eval { ( caller() )[1] } );

sub X {
    my $arg = shift;

    my $db_path="$path_of_this_module/../../database/database.xml";

    open(my $fh, '>>', $db_path) or die "cannot open $db_path: $!\n";
    print $fh $arg;
    close($fh);
}

1;

当我现在调用 ./index.cgi 然后调用 ./perl/indexCheck.cgi 时,我会得到以下结果:

数据库/database.xml:

called from index.cgi
called from indexCheck.cgi

正是,我认为您正在寻找的东西。

关于Perl - 模块内文件的相对路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35104362/

相关文章:

windows - 批处理文件 : List all files in a directory with relative paths

perl - 一个模块在 Perl 核心中存在多久了?

perl - 在Perl中动态/递归地构建哈希?

perl - perl 脚本中的粘贴和 awk 错误

regex - 我应该如何结合这些正则表达式?

html - 如何在静态站点中创建根目录相关链接?

mysql - 如何匹配两个数据库表中的相关值?

python - Pydev 相对项目路径

perl - 为什么 sub 中的 use 语句全局适用?

perl - 是否有使用 Module::Build 编写测试(和构建)的文档?