为什么在使用'do'函数时无法加载Perl库?
我是Perl新手,正在更新一个旧的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音调已经在整个网站中使用。但是,该脚本可以
.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
使用
的值作为文件名,并将文件内容作为Perl脚本执行EXPR
就像do 'stat.pl';
除了更加高效和简洁之外,它还可以跟踪当前文件名中的错误消息,搜索eval `cat stat.pl`;
目录,并在找到文件时更新@INC
%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.