Ruby'de $ stdout ve STDOUT arasındaki fark


91

Ruby'de $stdout(önünde dolar işareti bulunur) ve STDOUT(büyük harflerle) arasındaki fark nedir? Çıktı yeniden yönlendirmesi yapılırken hangisi kullanılmalı ve neden? Aynısı $stderrve için de geçerliSTDERR .

Düzenleme: İlgili bir soru buldum .



@theTinMan Kısmen bir kopya. Ancak arasındaki faklılık dikkat edilmelidir $stdoutve STDOUTvs $stdinve STDINsimetrik olan arasındaki farklar $stdoutve $>vs $stdinve $<değillerdir.
skalee

Yanıtlar:


109

$stdoutmevcut standart çıktıyı temsil eden global bir değişkendir . standart çıktıyı temsil eden STDOUTbir sabittir ve tipik olarak varsayılan değerdir$stdout .

Sabit STDOUTolmakla, onu yeniden tanımlamamalısınız, ancak $stdouthatalar / uyarılar olmadan yeniden tanımlayabilirsiniz (yeniden tanımlama STDOUTbir uyarı doğuracaktır). örneğin şunları yapabilirsiniz:

$stdout = STDERR

Aynı şey için de geçerli $stderrveSTDERR


Bu nedenle, sorunuzun diğer bölümünü yanıtlamak için, çıktıyı yönlendirmek için sabitleri değil global değişkenleri kullanın. Kodunuzda daha sonra değiştirmeye dikkat edin, global değişkenleri yeniden tanımlamak uygulamanızın diğer bölümlerini etkileyebilir.


3
Aslında, çıktıyı yeniden yönlendirmek istiyorsanız, muhtemelen $>varsayılan çıktı akışını kullanmamalısınız $stdout.
Jörg W Mittag

10
Takma ad yazan ve takma ad olan başka bir soruya bir yorum buldum , bu nedenle birini yeniden atamak diğerini etkileyecektir. $stdout$>
jrdioko

9
@jrdioko: Haklısın. Görünüşe göre, sadece her gün yeni bir şeyler öğrenmekle kalmıyorum, aynı zamanda her gün bir şeyi unutuyorum :-)
Jörg W Mittag

2
Ve daha fazlasını okurken , basit atama yerine IO # yeniden açmayı kullanmak daha iyi gibi görünüyor .
jrdioko

@jrdioko Neden böyle bir IO#reopendurumda kullanmanın daha iyi olduğunu düşünüyorsunuz $stdout? Bu fikre kesinlikle katılmıyorum. $stdout.reopenYöntem mutasyon onun alıcısı ve ayrıca etkileyecektir STDOUTsen yeniden değil eğer $stdoutdaha önce. Eşanlamlı olmaları amaçlanmamıştır, görev nedeniyle farklı değerlere sahip olduklarında ve STDOUTamacını bozduğunuzu yeniden açarak kötü bir şey değildir .
skalee

5
  • STDOUT küresel bir sabittir, bu yüzden değiştirilmemelidir.
  • $stdout önceden tanımlanmış bir değişkendir, bu nedenle değiştirilebilir.

Yönlendirme yapmak için kabuğu kullanıyorsanız:

$ ruby test.rb > test.log

betiğinizin dosya tanımlayıcısı olarak hangisini kullandığınız önemli değildir, komut dosyanız çalıştırılmadan önce belirlenir.

Ancak, İşletim Sisteminin STDOUT dosya tanımlayıcısını Ruby komut dosyanızın içinden değiştirmeye çalışıyorsanız, örneğin çıktıları haftanın o anki gününe göre dönen bir günlük dosyaları kümesine göndermek için, o zaman emin olmak isteyeceksiniz. kullanıyorsun $stdout.


5
"STDOUT global bir sabittir, bu yüzden değişmeyecek". Değiştirilebilen bir sabittir, ancak bir uyarı verilecektir. STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
The Tin Man

Ahh evet, öyleyse "değiştirilmemeli" demelisin. Teşekkürler!
shakerlxxv

5

Her ikisi de $stdoutve STDOUTfarklı anlamları var. Ruby'nin belgeleri bu konuda oldukça açık:

  • $stdout - Mevcut standart çıktı.
  • STDOUT- Standart çıktı. $ Stdout için varsayılan değer.

Standart çıktıya yazmak istediğinizde, aslında geçerli standart çıktıyı kastediyorsunuz , bu yüzden yazmalısınız $stdout.

STDOUTişe yaramaz da değil. Varsayılan değeri saklar $stdout. Daha önce yeniden $stdoutatarsanız, onu önceki değere geri yükleyebilirsiniz$stdout = STDOUT .

Ayrıca, önceden tanımlanmış bir değişken daha var:

  • $>- Varsayılan olarak print, printf için varsayılan çıktı $stdout.

Ancak Ruby 2.3'te bunun bir takma adı gibi davranması gibi görünüyor $stdout. Yeniden atama $stdout, değerini değiştirir $>ve bunun tersi de geçerlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.