前段时间,我问了一个问题:How do I redefine built in Perl functions?
答案对我很有帮助。我有一个包覆盖了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
现在我收到这条消息:
Can't locate object method "CHECK" via package "Data::Dumper"
我该如何解决?
答案 0 :(得分: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.
$
为何会出现特定错误?
perl -MO=Deparse -e 'print CHECK Data::Dumper 1';
print 'Data::Dumper'->CHECK(1);
此外,您正在使用全局文件句柄,这是有问题的。
使用这种表示法:
open my $fh, '<' , $foo ;
print <$fh>;
close $fh;
这些更有益的是当它们超出范围时它们会自动关闭。
答案 1 :(得分:1)
比较
> perl -MData::Dumper -e'local*_=*STDOUT;print _ Data::Dumper->Dump([2]);'
Can't locate object method "_" via package "Data::Dumper" at -e line 1.
到
> perl -MData::Dumper -e'local*_=*STDOUT;print _ ( Data::Dumper->Dump([2]) );'
$VAR1 = 2;
我在“STDOUT”中使用了一个不同的名称,因为它似乎只是在间接对象不是内置句柄时才会出错。
答案 2 :(得分:1)
这将有效并且不会产生错误......
print {*CHECK} Data::Dumper->Dump(\@a);
这可以防止它被混淆"Indirect Object Syntax"
但是我建议转向使用CHECK和其他special named code blocks in Perl,并使用词法变量来处理文件句柄是首选方法。 PBP