8
votes

Existe-t-il un moyen de capturer la sortie d'impression de sous-programme à une variable afin que je puisse l'envoyer à stardr à la place?

Supposons que nous ayons:

sub test {
        print "testing\n";
}


0 commentaires

4 Réponses :


12
votes

oui il y a. Imprimer CODE> Envoie sa sortie sur le fichier "sélectionné", qui est généralement stdout code>. Mais Perl fournit le Sélectionnez code> fonction pour que vous puissiez le changer. XXX

La fonction code> SELECT CODE> renvoie la fonction de fichier précédemment sélectionnée, vous pouvez ainsi la capturer et la restaurer ultérieurement. P>

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


1 commentaires

+1 Notez qu'une exception fatale dans le test () laissera une touche de fichier non standard () D, c'est pourquoi je suis local () ize dans ma réponse ci-dessous.



9
votes

Scoping dynamique de Perl via local () n'est pas souvent utilisé, mais cela me frappe comme une bonne application pour cela: xxx pré>

l'appel à test () code> dans le bloc ci-dessus - ainsi que sur tout ce que test () peut appeler - aura STDOUT de manière dynamique de votre duplicata de STDRERR. Lorsque le contrôle quitte le bloc, même si par matrice () code> ING, STDOUT sera restauré à tout ce qu'il était avant le bloc p>

généralisé: p>

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 commentaires

+1 Cela fonctionnera même si la fonction donnée est imprimée sur stdout explicitement.



3
votes

Entre-temps, vous pouvez également "capturer la sortie d'impression d'un sous-programme à une variable."

passe juste un scalaire réfer à Ouvrir : xxx < p> sortie: xxx


0 commentaires

1
votes

Ce travail pour moi xxx


1 commentaires

Ce code ne fonctionnera pas et n'imprimera rien au lieu du résultat imprimé par & test (); Le code suivant fonctionnera: do {local * stdout; ouvrir (stdout, ">", \ $ résultat); &test(); }; imprimer $ résultat;