下面的 Perl 脚本输出“成功”,正如你所期望的:
use Fcntl qw(:DEFAULT :flock);
sysopen(LF, "test.txt", O_RDONLY | O_CREAT) or die "SYSOPEN FAIL: $!";
if(flock(LF, LOCK_EX)) { print "SUCCESS.\n"; }
else { print "FAIL: $!\n"; }
但是现在,将第一行替换为
require "testlib.pl";
其中 testlib.pl 包含
use Fcntl qw(:DEFAULT :flock);
1;
现在,奇怪的是,脚本失败,像这样:
FAIL: Bad file descriptor
问题:为什么?
已添加:
现在我知道为什么了-谢谢!-我想知道解决此问题的最佳方法是什么:
只需执行use Fcntl
两次,一次在主脚本中,一次在所需的库中(主脚本和库都需要它)。
将 O_RDONLY 替换为 & amp;O_RDONLY 等。
将 O_RDONLY 替换为 O_RDONLY () 等。
还有别的吗?
通过前面的use
,您剥夺了 Perl 解析器的知识O_RDONLY
等。是无参数的子例程。在这种情况下,您必须更加详细:
sysopen(LF, "test.txt", O_RDONLY() | O_CREAT()) or die "SYSOPEN FAIL: $!";
if(flock(LF, LOCK_EX())) { print "SUCCESS.\n"; }
编辑:为了进一步阐述,没有括号,O_RDONLY
和O_CREAT
被解释为 barewords(字符串),当二进制或 'ed 在一起时,它们的行为不像你期望的那样:
$ perl -le 'print O_RDONLY | O_CREAT'
O_SVOO\Y
(各个字符按位或拼在一起。)
在这种情况下,字符串“O_SVOO\ Y”(或您系统上的任何内容)被解释为数字 0 到sysopen
,因此只要O_RDONLY
为 0(通常)并且文件已经存在(因此O_CREAT
是多余的)。但是fcntl
显然不是数字非参数
$ perl -e 'flock STDOUT, "LOCK_EX" or die "Failed: $!"'
Failed: Bad file descriptor at -e line 1.
同样:
$ perl -e 'flock STDOUT, LOCK_EX or die "Failed: $!"'
Failed: Bad file descriptor at -e line 1.
然而:
$ perl -e 'use Fcntl qw(:flock); flock STDOUT, LOCK_EX or die "Failed: $!"'
(no output)
最后,请注意use strict
提供了许多有用的线索。
然后,行use Fcntl qw(:DEFAULT :flock);
不仅为您加载 Fcntl 库,而且还将一些符号导出到脚本的命名空间中。如果将其移动到不同的范围,则常量 O_RDONLY,O_CREAT,LF 和 LOCK_EX 将不再对您可用,并且您的代码不会做同样的事情[但是您仍然可以访问它们,因为它们是 AME-
这在EXPORTED SYMBOLS下的文档中有描述:
默认情况下,系统的 F_* 和 O_* 常量(例如 F_DUPFD 和 O_CREAT)以及 FD_CLOEXEC 常量将导出到您的命名空间中。
您可以使用标记“:flock”请求提供 flock () 常量(LOCK_SH 、 LOCK_EX 、 LOCK_NB 和 LOCK_UN)。请参见 Exporter。
如果添加行
use strict;
use warnings;
到你的脚本的顶部,你会得到更多的信息性错误消息,如“名称”main::O_RDONLY“只使用一次:可能的类型在行...”,这将给你一个线索,这些常量定义不再可见。
编辑:为了回答你的问题,最好的做法是 # 1,在每个需要它的文件中包含 use 语句。请参阅perldoc -f use-Fcntl 库只包含一次,但每次需要时都会进行 import()调用,这就是你想要的。

使用相当于:
BEGIN { require Module; Module->import( LIST ); }
保证导入函数在代码开始执行之前可用。当您用 require 替换 use 时,它只是在程序中存在的词法点读取代码。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(34条)