如何在Perl中正确地重新定义'open'?

mmc*_*coo 3 perl redefine built-in

前段时间,我问一个问题:如何重新定义内置的Perl函数?

答案对我很有帮助.我有一个包覆盖了Perl的'open'功能,使我能够记录文件访问.

现在我来一个破坏原始代码功能的案例.

use strict;
use warnings;
use Data::Dumper;

sub myopen (*;@) {
  my $p;
  my $retval = CORE::open($p, $_[1]);
  {
    no strict;
    *{"main::$_[0]"} = $p;
  }
  return $retval;
}

BEGIN {
  *CORE::GLOBAL::open = *myopen;
};

my @a = (1, 2, 3);

open(CHECK, ">dump") or print "UNABLE TO OPEN DUMPER FILE: $!\n";
print CHECK "test\n";
print CHECK Data::Dumper->Dump(\@a);
close CHECK
Run Code Online (Sandbox Code Playgroud)

现在我收到这条消息:

Can't locate object method "CHECK" via package "Data::Dumper"
Run Code Online (Sandbox Code Playgroud)

我如何解决它?

Ken*_*ric 8

尝试使用"检查"以外的名称.

"CHECK"是一个在编译期间调用的特殊函数,你真的不应该使用它.

$ open CHECK , '<', 'foo.txt'; 
Took 0.00224494934082031 seconds.

Runtime error: Undefined subroutine &Devel::REPL::Plugin::Packages::DefaultScratchpad::CHECK called at (eval 329) line 5.

$ open CHECKS , '<', 'foo.txt'; 
Took 0.00155806541442871 seconds.

$
Run Code Online (Sandbox Code Playgroud)

为什么那个具体错误?

perl -MO=Deparse -e 'print CHECK Data::Dumper 1';
print 'Data::Dumper'->CHECK(1);
Run Code Online (Sandbox Code Playgroud)

此外,您正在使用全局文件句柄,这是有问题的.

使用这种表示法:

open my $fh, '<' , $foo ; 
print <$fh>;
close $fh;
Run Code Online (Sandbox Code Playgroud)

这些是额外的好处,当它们超出范围时它们会自动关闭.

  • @j_random_hacker:使用PerlCritic会带来一些Perl爱回来;-) (3认同)