Perl 5:无法获取文件句柄描述符

时间:2017-08-20 14:24:48

标签: perl file file-descriptor

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.

错误在哪里?

1 个答案:

答案 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