2010-01-01 6 views
3

Ruby a des constantes et des variables globales pour stdio.Ruby stdio consts et globals, quelles sont les utilisations?

A savoir, les consts STDIN, STDOUT, STDERR et leurs homologues variables, $stdin, $stdout, $stderr. Je comprends la différence entre une constante et une variable. Je sais que les constantes sont immuablement fixées aux descripteurs de fichiers au moment où le script a été exécuté.

Je comprends également que vous pouvez modifier (certaines des) les variables lors de l'exécution.

Je suis curieux en ce qui concerne les utilisations pratiques de cette fonctionnalité. Pourquoi voudriez-vous le faire? Que pouvez-vous réaliser?

Voir un exemple de code, ou même simplement utiliser des cas, extrait de projets dans le monde réel serait génial.


Mise à jour: D'après ce que je crois à ce jour, il semble que lors de l'écriture de vos propres bibliothèques/programmes, vous devriez préférer utiliser les variables sur les constantes, de sorte que ses utilisateurs puissent poursuivre muck avec elle. Droite?

Répondre

3

Une version plus élaborée de cette fonction est en cours d'utilisation dans le code de production:

#!/usr/bin/env ruby -rstringio 

def capture_stdout 
    $stdout = StringIO.new 
    begin 
    yield 
    $stdout.string 
    ensure 
    $stdout = STDOUT 
    end 
end 

output = capture_stdout do 
    print "Line" 
    puts " 1" 
end 

p output  # => "Line 1\n" 

Il est utilisé dans les tests unitaires qui veulent savoir ce qui a été écrit sur la console en utilisant print ou puts.

Les $ des variables vous permettent de donner différents objets IO Ruby pour stdout, stdin, stderr:

$stdout = buffer 

les constantes rendent facile d'obtenir les dos des variables $ à leur valeur d'origine (lorsque votre programme a commencé):

$stdout = STDOUT 
+0

Pourquoi ne pas initialiser le tampon à un StringIO à la place? – kch

+0

Quand j'ai écrit cette fonction il y a un milliard d'années, j'étais un chanteur et je ne connaissais pas StringIO. Heck, c'était Ruby 1.6 alors. Aujourd'hui, c'est la première fois que je regarde ce code depuis. Mais si le code utilise StringIO est un problème périphérique. –

+1

En effet, c'est un problème périphérique, et stringio étant moins de code, cela facilite la lisibilité de la partie pertinente de l'exemple. Je vais accepter votre réponse. Je vais le modifier pour utiliser stringio, n'hésitez pas à le retourner si vous n'aimez pas mes changements. – kch

0

Vous pouvez envoyer une partie de votre sortie vers un fichier, puis la replacer sur la console lorsque vous avez terminé.

+0

Le soin d'élaborer sur lui? – kch

+0

Quelle partie de l'écriture dans un fichier ne comprenez-vous pas? –

+1

Voir où j'écris "les utilisations pratiques de cette fonctionnalité"? – kch

2

Le livre de Matsumoto semble donner la réponse. Citation de 9.7.1.4 Flux prédéfinis: "Les fonctions globales comme print et puts écrivent dans $ stdout par défaut Si un script modifie la valeur de cette variable globale, cela changera le comportement de ces méthodes."

Il me semble que l'idée est simplement de permettre une solution facile à un programme éventuellement mal implémenté.

+1

s/programme éventuellement mal implémenté/scripts unix soi-disant jetables/ – kch

+0

notez que 'print' et' puts' écrivent réellement dans '$>', qui est initialement défini sur '$ stdout', mais peut être modifié. Ou alors je pense. – kch

+0

Ah, hum sed. Toujours hilarant. –

1
$stderr = File.open 'error.log', 'w' 

Toutes les erreurs seront écrites error.log

+0

Hum. C'est logique, si vous avez un fichier de configuration qui détermine que vous devriez vous connecter à un fichier au lieu de stderr. – kch

Questions connexes