Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在使用'do'函数时无法加载Perl库?_Perl_Subroutine - Fatal编程技术网

为什么在使用'do'函数时无法加载Perl库?

为什么在使用'do'函数时无法加载Perl库?,perl,subroutine,Perl,Subroutine,我是Perl新手,正在更新一个旧的Perl网站。每个.pl文件的顶部似乎都有一行: do "func.inc"; 所以我想我可以用这个文件来标记一个全局使用的子程序 func公司 index.pl 但是,我得到了这个错误: Undefined subroutine &main::foobar called at /path/to/index.pl line 4. 这两个文件都在同一个目录中,而且func.inc中的subs音调已经在整个网站中使用。但是,该脚本可以

我是Perl新手,正在更新一个旧的Perl网站。每个
.pl
文件的顶部似乎都有一行:

do "func.inc";
所以我想我可以用这个文件来标记一个全局使用的子程序

func公司 index.pl 但是,我得到了这个错误:

Undefined subroutine &main::foobar called at /path/to/index.pl line 4.
这两个文件都在同一个目录中,而且
func.inc
中的subs音调已经在整个网站中使用。但是,该脚本可以在Linux生产环境中工作,但不适用于我的Windows 7开发环境(我使用的是ActivePerl)

更新: 看起来没有包含该文件;如果文件是使用绝对路径包含的,则子文件将起作用

do "C:/path/to/func.inc";
。。。因此,相对路径似乎不适用于我的本地开发环境,但它们通过在生产环境中工作。但是这对我没有好处,因为我的开发机器上的绝对路径对于实时服务器不起作用

如何使
do
在我的Windows 7 dev计算机上使用相对路径工作

更新2:
我正在使用Perl
-T
开关。不幸的是,这会从@INC中删除“.”,从而阻止我们使用
do
的相对路径。我删除了这个开关,旧代码现在可以工作了。我知道这不是一个好的做法,但不幸的是,我使用的是旧代码,所以我似乎没有选择。

我会首先检查文件是否已实际加载,并提到如果找到文件,它会更新
%INC
。文档中还有更多信息。

使用该子例程的方式与使用任何其他子例程的方式相同。无论您是否加载了
do
。但是,您不应该为此使用
do
。有关从其他文件加载子程序的详细说明,请参阅中的“程序包”一章。简言之,改用


有关详细信息,请参阅文档。您需要将func.inc(也可以调用func.pl,因为pl是“perl-library”)放在perl查找库的目录之一中。这可能与包含index.pl的目录不同。将func.inc放在
@inc
的某个地方,或将其目录添加到
@inc
do
如果无法加载文件,也不会死掉,因此不会告诉您它失败了。这就是为什么不应该使用
do
加载库的原因。:)

确保func.inc路径正确

do "func.inc" 
表示func.inc与perl脚本位于同一路径。检查正确的路径,然后执行此操作

do "/path/func.inc"

确保路径正确,请使用:


#!/usr/bin/perl 
require("func.inc");
print "Content-type: text/html\n\n"; 
print foobar(); 
上面写着

  • do EXPR
    使用
    EXPR
    的值作为文件名,并将文件内容作为Perl脚本执行

    do 'stat.pl';
    
    就像

    eval `cat stat.pl`;
    
    除了更加高效和简洁之外,它还可以跟踪当前文件名中的错误消息,搜索
    @INC
    目录,并在找到文件时更新
    %INC

因此,要看到所有这些都在起作用,可以说C:\Cygwin\tmp\mylib\func.inc

sub hello {
  print "Hello, world!\n";
}

1;
我们在以下程序中使用它:

#!/usr/bin/perl

use warnings;
use strict;

# your code may have unshift @INC, ...
use lib "C:/Cygwin/tmp/mylib";

my $func = "func.inc";

do $func;

# Now we can just call it. Note that with strict subs enabled,
# we have to use parentheses. We could also predeclare with
# use subs qw/ hello /; 
hello();

# do places func.inc's location in %INC
if ($INC{$func}) {
  print "$0: $func found at $INC{$func}\n";
}
else {
  die "$0: $func missing from %INC!";
}
它的产量是

Hello, world! ./prog: func.inc found at C:/Cygwin/tmp/mylib/func.inc ./prog: do func.inc: at ./prog line 13. 对每种情况的解释如下

do
无法读取该文件 如果我们将
func.inc
重命名为
nope.inc
并重新运行该程序,我们将得到

./prog: do func.inc: No such file or directory at ./prog line 12. 现在运行程序,我们可以

./prog: do func.inc: Missing right curly or square bracket at C:/Cygwin/tmp/mylib/func.inc line 4, at end of line syntax error at C:/Cygwin/tmp/mylib/func.inc line 4, at EOF 现在输出是

Hello, world! ./prog: func.inc found at C:/Cygwin/tmp/mylib/func.inc ./prog: do func.inc: at ./prog line 13. ./prog:do func.inc:at./prog第13行。 因此,没有回报值,成功就像失败。我们可以使检查
do
结果的代码复杂化,但更好的选择是始终在Perl库和模块的末尾返回一个真值


请注意,即使启用了污染检查(
-T
),程序也能正确运行。试试看!一定要读。

啊,我明白了。对于我自己实现的任何东西,我都会使用包,但我不确定使用包重新实现现有系统是否明智,因为我是Perl初学者。这与包无关。您有点落后,因此您可能希望通过阅读学习Perl和中级Perl来迎头赶上。我非常详细地解释了所有这些内容。@brian这些是正确的链接吗?这些是我的书的标题。你想在哪里买就在哪里。:)“learn.perl.org不是我这本书的网站。@布赖恩,谢谢你澄清这一点,我只是想确定一下。我这么问也是因为我想假设那个网站是你的!;-)您不想检查%INC。请不要使用do。请改用require。@brian谢谢,我将确保我不会为我编写的任何新代码而使用
do
!另外,学习Perl最糟糕的方法是阅读别人留给你的随机代码。你发现了他们所有的坏习惯和误解。更新2不正确。我正在写一个回答你的其他问题的答案,它解释了发生了什么,但是你把它删除了。code>-T不是严格的问题:它是一道护栏,可以阻止你从悬崖上摔下来。你已经承认自己是个初学者,所以慢下来,听听我们经验丰富的老兵们的宝贵建议吧!看来我是那个一直在做无端假设的人,为此我道歉。我希望你能原谅我的惊慌:我担心你会把你的脚打掉。生产站点中的这个巨大缺陷为您提供了一个极好的机会。这是一个关键的安全问题。让组织中的人员意识到这个问题,然后带头解决它。对于初学者来说,安全性不是问题,所以你需要快速阅读并成为专家。我们是来帮助你的。+1感谢你在这个帖子里的礼貌。我用的是
-T
开关-doh!但是,您是对的,代码应该使用
require
,因为这会检查Perl是否能够真正找到文件,而不是静默失败。Pl ./prog: do func.inc: Missing right curly or square bracket at C:/Cygwin/tmp/mylib/func.inc line 4, at end of line syntax error at C:/Cygwin/tmp/mylib/func.inc line 4, at EOF
sub hello {
  print "Hello, world!\n";
}
./prog: do func.inc: at ./prog line 13.