Unterschied zwischen $ stdout und STDOUT in Ruby

88

Was ist in Ruby der Unterschied zwischen $stdout(vorangestellt von einem Dollarzeichen) und STDOUT(in Großbuchstaben)? Welche sollte bei der Ausgabeumleitung verwendet werden und warum? Das gilt auch für $stderrund STDERR.

Bearbeiten: Habe gerade eine verwandte Frage gefunden .

jrdioko
quelle
@theTinMan Etwas ist es ein Duplikat. Es muss jedoch beachtet werden, dass die Unterschiede zwischen $stdoutund STDOUTvs $stdinund STDINsymetrisch sind, die Unterschiede zwischen $stdoutund $>vs $stdinund $<jedoch nicht.
Skalee

Antworten:

105

$stdoutist eine globale Variable , die die aktuelle Standardausgabe darstellt. STDOUTist eine Konstante, die die Standardausgabe darstellt, und ist normalerweise der Standardwert von $stdout.

Da STDOUTes sich um eine Konstante handelt, sollten Sie sie nicht neu definieren. Sie können sie jedoch $stdoutohne Fehler / Warnungen neu definieren (eine Neudefinition STDOUTlöst eine Warnung aus). Sie können beispielsweise Folgendes tun:

$stdout = STDERR

Gleiches gilt für $stderrundSTDERR


Um den anderen Teil Ihrer Frage zu beantworten, verwenden Sie die globalen Variablen, um die Ausgabe umzuleiten, nicht die Konstanten. Achten Sie nur darauf, dass Sie es später in Ihrem Code wieder ändern. Eine Neudefinition globaler Variablen kann sich auf andere Teile Ihrer Anwendung auswirken.

Brian
quelle
3
Wenn Sie die Ausgabe umleiten möchten, sollten Sie wahrscheinlich $>den Standardausgabestream verwenden, nicht $stdout.
Jörg W Mittag
9
Ich habe gerade einen Kommentar zu einer anderen Frage gefunden , die Aliase sagt $stdoutund $>ist. Wenn Sie also eine neu zuweisen, wirkt sich dies auf die andere aus.
Jrdioko
9
@jrdioko: Du hast recht. Anscheinend lerne ich nicht nur jeden Tag etwas Neues, ich vergesse auch jeden Tag etwas :-)
Jörg W Mittag
2
Wenn Sie mehr lesen, klingt es so, als wäre es besser, IO # reopen anstelle einer einfachen Zuweisung zu verwenden.
jrdioko
@jrdioko Warum denkst du, ist es besser, IO#reopenim Falle von zu verwenden $stdout? Ich bin mit dieser Meinung überhaupt nicht einverstanden. Die $stdout.reopenMethode mutiert den Empfänger und dies wirkt sich auch aus, STDOUTwenn Sie zuvor keine Neuzuweisung vorgenommen $stdouthaben. Sie sind nicht als Synonyme gedacht, es ist nichts Schlimmes, wenn sie aufgrund der Zuweisung unterschiedliche Werte haben und wenn Sie das öffnen STDOUT, brechen Sie den Zweck.
Skalee
5
  • STDOUT ist eine globale Konstante und sollte daher nicht geändert werden.
  • $stdout ist eine vordefinierte Variable, die geändert werden kann.

Wenn Sie die Shell zum Umleiten verwenden:

$ ruby test.rb > test.log

Dann spielt es keine Rolle, welche Sie als Dateideskriptor für Ihr Skript verwenden, bevor Ihr Skript ausgeführt wird.

Wenn Sie jedoch versuchen, den Dateideskriptor für STDOUT des Betriebssystems in Ihrem Ruby-Skript zu ändern, um beispielsweise die Ausgabe basierend auf dem aktuellen Wochentag an einen rotierenden Satz von Protokolldateien zu senden, sollten Sie dies sicherstellen Sie verwenden $stdout.

shakerlxxv
quelle
5
"STDOUT ist eine globale Konstante, daher wird sich nichts ändern". Es ist eine Konstante, die geändert werden kann, aber eine Warnung wird ausgegeben. STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
der Blechmann
Ahh ja, sollte also sagen "damit es nicht geändert wird". Vielen Dank!
Shakerlxxv
5

Beide $stdoutund STDOUThaben unterschiedliche Bedeutungen. Rubys Dokumentation zu diesem Thema ist ziemlich klar:

  • $stdout - Die aktuelle Standardausgabe.
  • STDOUT- Die Standardausgabe. Der Standardwert für $ stdout.

Wenn Sie in die Standardausgabe schreiben möchten, meinen Sie tatsächlich die aktuelle Standardausgabe, daher sollten Sie in diese schreiben $stdout.

STDOUTist auch nicht nutzlos. Es speichert den Standardwert für $stdout. Wenn Sie jemals neu zuweisen $stdout, können Sie den vorherigen Wert mit wiederherstellen $stdout = STDOUT.

Darüber hinaus gibt es noch eine vordefinierte Variable:

  • $>- Die Standardausgabe für print, printf, die $stdoutstandardmäßig verwendet wird.

Es sieht jedoch so aus, als ob es sich in Ruby 2.3 einfach als Alias ​​für verhält $stdout. Durch Neuzuweisung $stdoutwird der Wert von geändert $>und umgekehrt.

Skalee
quelle