2009-05-02 4 views
3

Vor einiger Zeit stelle ich eine Frage: How do I redefine built in Perl functions?Wie kann ich "offen" in Perl neu definieren?

Und die Antworten haben mir gut gedient. Ich habe ein Paket, das die offene Funktion von Perl außer Kraft setzt und es mir ermöglicht, den Dateizugriff zu protokollieren.

Jetzt habe ich auf einen Fall kommen, die die Funktionalität des ursprünglichen Codes bricht. Jetzt

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 

ich diese Meldung:

Can't locate object method "CHECK" via package "Data::Dumper" 

Wie kann ich das Problem beheben?

+0

Wenn das der vollständige Fehler ist, verwendet es indirect Objektsyntax für das falsche Objekt. Versuchen Sie CHECK-> print (...) und sehen Sie, ob Sie den gleichen Fehler bekommen. – Anonymous

Antwort

1

vergleichen:

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

zu

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

ich einen anderen Namen von „STDOUT“ verwendet, weil es scheint, wird nur das indirekte Objekt falsch, wenn es handelt nicht über eine eingebaute in ist.

8

Versuchen Sie einen anderen Namen als "CHECK" verwenden.

"CHECK" ist eine spezielle Funktion, die während der Kompilierzeit aufgerufen wird, und Sie sollten sie wirklich nicht verwenden.

$ 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. 

$ 

Warum, dass bestimmte Fehler?

perl -MO=Deparse -e 'print CHECK Data::Dumper 1'; 
print 'Data::Dumper'->CHECK(1); 

Auch sind Sie globale Datei behandelt, die problematisch sind.

Verwendung dieser Notation:

open my $fh, '<' , $foo ; 
print <$fh>; 
close $fh; 

Dies sind besonders vorteilhaft ist, sie selbst zu schließen, wenn sie sich außerhalb des Geltungsbereichs gehen.

+0

+1, nette Analyse des Problems und Sie vorgeschlagen, die richtige Lösung (open() saner 3-arg-Syntax, mit dem Dateihandle in einer lexikalischen Variable). Und ich hasse Perl für Dinge wie diese. –

+3

@j_random_hacker: PerlCritic bringt Perl Liebe zurück ;-) – draegtun

+0

@draegtun: Perl :: Critic sieht interessant aus (obwohl ich Angst habe, was es über meine große Codebase von altem, altem Code sagen wird ... :)) –

1

Dies funktioniert und ohne den Fehler zu produzieren ...

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

Dies hält es verwechselt werden hat eine "Indirect Object Syntax"

Allerdings empfehle ich Lenkung frei von CHECK und anderen special named code blocks in Perl und mit lexikalischen Variablen für Dateihandles ist die bevorzugte Methode. PBP

Verwandte Themen