Perbedaan antara $ stdout dan STDOUT di Ruby

89

Di Ruby, apa perbedaan antara $stdout(diawali dengan tanda dolar) dan STDOUT(dalam huruf besar semua)? Saat melakukan pengalihan keluaran, mana yang harus digunakan dan mengapa? Hal yang sama berlaku untuk $stderrdan STDERR.

Edit: Baru saja menemukan pertanyaan terkait .

jrdioko
sumber
kemungkinan duplikat dari Apa perbedaan antara STDIN dan $ stdin di Ruby?
Manusia Timah
@ theTinMan Agak itu duplikat. Namun harus dicatat bahwa perbedaan antara $stdoutdan STDOUTvs $stdindan STDINadalah simetris, sedangkan perbedaan antara $stdoutdan $>vs $stdindan $<tidak.
skalee

Jawaban:

108

$stdoutadalah variabel global yang mewakili keluaran standar saat ini. STDOUTadalah konstanta yang mewakili keluaran standar dan biasanya merupakan nilai default $stdout.

Dengan STDOUTmenjadi sebuah konstanta, Anda tidak boleh mendefinisikannya kembali, namun, Anda dapat mendefinisikan ulang $stdouttanpa kesalahan / peringatan (mendefinisikan ulang STDOUTakan menimbulkan peringatan). misalnya, Anda dapat melakukan:

$stdout = STDERR

Hal yang sama berlaku untuk $stderrdanSTDERR


Jadi, untuk menjawab bagian lain dari pertanyaan Anda, gunakan variabel global untuk mengarahkan keluaran, bukan konstanta. Berhati-hatilah untuk mengubahnya lebih lanjut dalam kode Anda, mendefinisikan ulang variabel global dapat memengaruhi bagian lain dari aplikasi Anda.

Brian
sumber
3
Sebenarnya, jika Anda ingin mengalihkan keluaran, Anda mungkin harus menggunakan $>aliran keluaran default, bukan $stdout.
Jörg W Mittag
10
Baru saja menemukan komentar untuk pertanyaan lain yang mengatakan $stdoutdan $>merupakan alias, jadi penugasan ulang satu akan mempengaruhi yang lain.
jrdioko
9
@jrdioko: Anda benar. Ternyata, saya tidak hanya belajar sesuatu yang baru setiap hari, saya juga melupakan sesuatu setiap hari :-)
Jörg W Mittag
2
Dan membaca lebih banyak, sepertinya lebih baik menggunakan IO # reopen daripada tugas sederhana.
jrdioko
@jrdioko Menurut Anda, mengapa lebih baik menggunakan IO#reopenjika terjadi $stdout? Saya sangat tidak setuju dengan pendapat ini. The $stdout.reopenMetode bermutasi penerima dan yang juga akan mempengaruhi STDOUTjika Anda belum ditugaskan $stdoutsebelumnya. Mereka tidak dimaksudkan untuk menjadi sinonim, tidak ada yang buruk ketika mereka memiliki nilai yang berbeda karena tugas, dan dengan membuka kembali STDOUTAnda melanggar tujuannya.
skalee
5
  • STDOUT adalah konstanta global, jadi tidak boleh diubah.
  • $stdout adalah variabel yang telah ditentukan sebelumnya, sehingga dapat diubah.

Jika Anda menggunakan shell untuk melakukan pengalihan:

$ ruby test.rb > test.log

maka tidak masalah mana yang Anda gunakan sebagai deskriptor file untuk skrip Anda ditentukan sebelum skrip Anda dieksekusi.

Namun, jika Anda mencoba mengubah deskriptor file untuk STDOUT OS dari dalam skrip Ruby Anda, misalnya untuk mengirim output ke sekumpulan file log yang berputar berdasarkan hari saat ini dalam seminggu, maka Anda pasti ingin memastikan Anda gunakan $stdout.

shakerlxxv
sumber
5
"STDOUT adalah konstanta global, jadi tidak akan berubah". Ini adalah konstanta, yang DAPAT diubah, tetapi peringatan akan dikeluarkan. STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
Manusia Timah
Ahh ya, jadi harus bilang "jadi tidak boleh diubah". Terima kasih!
shakerlxxv
5

Keduanya $stdoutdan STDOUTmemiliki arti yang berbeda. Dokumentasi Ruby cukup jelas tentang topik ini:

  • $stdout - Output standar saat ini.
  • STDOUT- Output standar. Nilai default untuk $ stdout.

Ketika Anda ingin menulis ke keluaran standar, maka yang Anda maksud adalah keluaran standar saat ini , jadi Anda harus menulis ke $stdout.

STDOUTtidak berguna juga. Ini menyimpan nilai default untuk $stdout. Jika Anda pernah menetapkan ulang $stdout, Anda dapat mengembalikannya ke nilai sebelumnya dengan $stdout = STDOUT.

Selain itu, ada satu lagi variabel standar:

  • $>- Output default untuk print, printf, yang merupakan $stdoutdefault.

Namun sepertinya di Ruby 2.3 itu hanya berperilaku sebagai alias untuk $stdout. Penetapan ulang $stdoutmengubah nilai $>dan sebaliknya.

skalee
sumber