2013-08-20 7 views
6

Ich schreibe einige Tests mit Test::More, und eine der Funktionen, die ich testen Drucke auf STDERR. Ich möchte die Ausgabe auf STDERR testen, bin aber ein wenig unsicher, wie das geht. Ich weiß, dass ich in der Nähe bin. Dies funktioniert:Wie kann ich STDERR mit Test :: More testen?

use strict; 
use warnings; 
use feature qw(say); 

close STDERR; 
open STDERR, ">", \my $error_string; 

say STDERR "This is my message"; 
say qq(The \$error_string is equal to "$error_string"); 

Dies gibt:

The $error_string is equal to "This is my message 
" 

aber ich will nicht, STDERR zu schließen. Ich möchte es nur kopieren.

Ich habe dies versucht:

use strict; 
use warnings; 
use feature qw(say); 

open my $error_fh, ">", my $error_string; 
open STDERR, ">&", $error_fh; 

say STDERR "This is my message"; 
close $error_fh; 
say qq(The \$error_string is equal to "$error_string"); 

Aber $error_string ist leer.

Was mache ich falsch?

Antwort

6

Für mich open STDERR, ">&", $error_fh (zusammen mit open STDERR, ">&" . fileno($error_fh)) keinen wahren Wert zurück. Ich denke, dass der >& Modus ein ziemlich direkter syntaktischer Zucker für einen dup Systemaufruf sein könnte, der auf einem Pseudo-Dateihandle wie nicht funktionieren würde.

Wie wäre es mit der Lokalisierung STDERR?

{ 
    local *STDERR = *$error_fh; 
    say STDERR "something"; 
} 
# STDERR restored 
+0

Dang. Ich dachte, ich hätte Autodie benutzt. Wenn ich es hinzufüge, bekomme ich 'GLOB (0x7fcb82829808) 'mit Modus'> & 'nicht öffnen können:' Bad file descriptor 'bei ./test.pl Zeile 11'. Lokalisieren STDERR sollte den Trick tun. –

2
# perl -MPerlIO::tee -MData::Printer -e 'my $output; STDERR->push_layer(tee=> \$output); warn "Danger, Will Robinson!"; p($output);' 
Danger, Will Robinson! at -e line 1. 
"Danger, Will Robinson! at -e line 1. 
"