2009-05-02 8 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

完全なエラーの場合は、間違ったオブジェクトに対してインダイレクトオブジェクト構文を使用しています。 CHECK-> print(...)を試して、同じエラーが発生するかどうかを確認してください。 – Anonymous

答えて

1

は比較:

> perl -MData::Dumper -e'local*_=*STDOUT;print _ (Data::Dumper->Dump([2]));' 
$VAR1 = 2; 

> perl -MData::Dumper -e'local*_=*STDOUT;print _ Data::Dumper->Dump([2]);' 
Can't locate object method "_" via package "Data::Dumper" at -e line 1. 

を、それは内蔵のハンドルではありませんときにのみ、間接オブジェクトの間違ったを取得するように見えるので、私は「STDOUT」から別の名前を使用しました。

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()のsaner 3-arg構文、ファイルハンドルを字句変数で指定)を提案しました。そして、私はこれが好きな人には嫌いです。 –

+3

@j_random_hacker:PerlCriticを使用すると、Perlの愛が戻ってくるでしょう;-) – draegtun

+0

@draegtun:Perl :: Criticは面白そうです(私は古いコードの大きなコードベースについて何か言いたいのですが... :)) –

1

これは動作し、エラーを生じることなくなります...

print {*CHECK} Data::Dumper->Dump(\@a); 

これは停止し、それが混同されているがあり、私はレキシカル変数をチェックして、他のspecial named code blocks in Perlを使用し、使用しての明確な操縦をお勧めしますしかし"Indirect Object Syntax"

filehandleの方が望ましい方法です。 PBP

関連する問題