2009-05-02 79 views
3

前段時間,我問一個問題:How do I redefine built in Perl functions?如何在Perl中重新定義'open'?

而且答案對我很好。我有一個壓縮Perl的「開放」功能的軟件包,使我能夠登錄文件訪問。

現在我來介紹一個打破原始代碼功能的案例。

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

如果這是完全錯誤,那麼它會在錯誤的對象上使用非直接對象語法。嘗試檢查 - >打印(...),看看你是否得到相同的錯誤。 – Anonymous 2009-05-02 00:18:23

回答

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; 

我從「標準輸出」使用不同的名字,因爲它似乎只得到間接的對象錯了,當它不是一個內置手柄。

8

嘗試使用「CHECK」以外的名稱

「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; 

這些是額外的有利的是他們自己關閉,當他們走出去的範圍。

+0

+1,對問題進行了很好的分析,並提出了正確的解決方案(open()的3-arg語法,文件句柄在詞法變量中)。而且,我討厭像這樣的東西。 – 2009-05-02 16:46:06