2013-05-17 4 views

Antwort

11

Ja, da ist. print sendet seine Ausgabe an das "ausgewählte" Dateihandle, das normalerweise STDOUT ist. Aber Perl bietet die select Funktion für Sie, um es zu ändern.

select(STDERR); 
&test;   # send output to STDERR 
select(STDOUT); # restore default output handle 

Die select Funktion gibt die zuvor ausgewählte Dateihandle, so können Sie es erfassen und später wiederherstellen.

my $orig_select = select(STDERR); 
&test; 
select($orig_select); 
+0

+1 Beachten Sie, dass eine schwerwiegende Ausnahme in Test() wird ein Nicht-Standard-FILEHANDLE select() d, verlassen, die ist warum ich lokal in meiner Antwort unten bin. – pilcrow

9

Perl dynamische Scoping über local() nicht oft verwendet wird, aber dies scheint mir eine gute Anwendung für sie:

test(); # to stdout 
{ 
    open(local *STDOUT, ">&STDERR") or die "dup out to err: $!"; 
    test(); # to stderr, locally calling it "STDOUT" 
} 
test(); # to stdout again 

Der Aufruf von test() im Block oben - sowie alles dass test() selbst aufrufen könnte - STDOUT wird dynamisch auf Ihr Duplikat von STDERR beschränkt. Wenn die Steuerung den Block verlässt, auch wenn durch die() ing wird STDOUT, was auch immer wieder hergestellt werden war es vor dem Block

generali:

sub out2err(&) { 
    my $user_block = shift; 
    open(local *STDOUT, ">&STDERR") or die $!; 
    $user_block->(); 
} 

test();    # to stdout 
out2err { test() }; # to stderr 
test();    # to stdout 
+1

+1 Dies funktioniert auch dann, wenn die angegebene Funktion explizit auf 'STDOUT' druckt. – chepner

3

der Zwischenzeit können Sie auch „Aufnehmen eines Druckausgabe des Unterprogramm auf eine Variable . "

einfach einen skalaren ref open passieren:

#! /usr/bin/env perl 
use common::sense; 
use autodie; 

sub tostring (&) { 
    my $s; 
    open local *STDOUT, '>', \$s; 
    shift->(); 
    $s 
} 

sub fake { 
    say 'lalala'; 
    say 'more stuff'; 
    say 1 + 1, ' = 2'; 
    say for @_; 
} 

for (tostring { fake(1, 2, 3) }) { 
    s/\n/\\n/g; 
    say "Captured as string: >>>$_<<<"; 
} 

Ausgang:

Captured as string: >>>lalala\nmore stuff\n2 = 2\n1\n2\n3\n<<<