test.pl:
#!/usr/bin/perl
use warnings;
BEGIN {
*CORE::GLOBAL::close = sub (;*) {
my @Args = @_;
my $FileNO = fileno($Args[0]);
print $FileNO, "\n";
CORE::close(@Args);
};
}
use lib '.';
use Test;
Test.pm:
package Test;
open(XXX, 'test.pl');
close(XXX);
1;
当我运行此程序(perl test.pl
)时,我得到:
Use of uninitialized value $FileNO in print at test.pl line 10.
close() on unopened filehandle 1 at test.pl line 11.
错误在哪里?
答案 0 :(得分:0)
您将整个@Args
数组传递给CORE::close
,这不是文件句柄。您需要传入数组的正确元素。这是一个从命令行获取文件名的示例,并做正确的事情:
use warnings;
use strict;
BEGIN {
*CORE::GLOBAL::close = sub (;*) {
my @Args = @_;
my $FileNO = fileno($Args[0]);
print $FileNO, "\n";
# the next line is where the issue is
CORE::close($Args[0]);
};
}
die "need file param" if ! @ARGV;
my $file = $ARGV[0];
open my $fh, $file or die $!;
close $fh or die $!;
我会更进一步了解你拥有的东西。首先,我将重新调整事物,以便覆盖CORE
函数在.pm
文件而不是测试文件中,然后我将切换到使用词法文件句柄,如全局裸字在这里不起作用:
Test.pm
:
package Test;
BEGIN {
*CORE::GLOBAL::close = sub (;*) {
my @Args = @_;
my $FileNO = fileno($Args[0]);
print $FileNO, "\n";
CORE::close($Args[0]);
};
}
1;
脚本文件:
use warnings;
use strict;
use lib '.';
use Test;
open my $fh, 'test.pl' or die $!;
close $fh or die $!;
在迁移代码和使用词法文件句柄之间,事情应该像你期望的那样工作。
运行脚本的输出:
3
...为确保一切正常,我将返回默认配置,其中覆盖在测试脚本中,而不是模块:
Test.pm
package Test;
open my $fh, 'test.pl' or die $!;
close $fh or die $!;
1;
...和脚本:
use warnings;
use strict;
BEGIN {
*CORE::GLOBAL::close = sub (;*) {
my @Args = @_;
my $FileNO = fileno($Args[0]);
print $FileNO, "\n";
CORE::close($Args[0]);
};
}
use lib '.';
use Test;
输出:
4