ความแตกต่างระหว่าง $ stdout และ STDOUT ใน Ruby


91

ใน Ruby ความแตกต่างระหว่าง$stdout(นำหน้าด้วยเครื่องหมายดอลลาร์) กับSTDOUT(ตัวพิมพ์ใหญ่ทั้งหมด) คืออะไร? เมื่อทำการเปลี่ยนทิศทางเอาต์พุตควรใช้ข้อใดและเพราะเหตุใด เดียวกันจะไปสำหรับและ$stderrSTDERR

แก้ไข:เพียงแค่พบคำถามที่เกี่ยวข้อง



@theTinMan ค่อนข้างจะซ้ำกัน อย่างไรก็ตามต้องสังเกตว่าในขณะที่ความแตกต่างระหว่าง$stdoutและSTDOUTvs $stdinและSTDINเป็นแบบสมมาตรความแตกต่างระหว่าง$stdoutและ$>vs $stdinและ$<ไม่ใช่
skalee

คำตอบ:


109

$stdoutเป็นตัวแปรส่วนกลางที่แสดงถึงเอาต์พุตมาตรฐานปัจจุบัน STDOUTเป็นค่าคงที่$stdoutเป็นตัวแทนส่งออกมาตรฐานและโดยทั่วไปจะมีค่าเริ่มต้นของ

ด้วยSTDOUTการเป็นค่าคงที่คุณไม่ควรกำหนดใหม่อย่างไรก็ตามคุณสามารถกำหนดใหม่ได้$stdoutโดยไม่มีข้อผิดพลาด / คำเตือน (การกำหนดใหม่STDOUTจะทำให้เกิดคำเตือน) ตัวอย่างเช่นคุณสามารถทำได้:

$stdout = STDERR

เช่นเดียวกันสำหรับ$stderrและSTDERR


ดังนั้นเพื่อตอบคำถามส่วนอื่นให้ใช้ตัวแปรส่วนกลางเพื่อเปลี่ยนทิศทางผลลัพธ์ไม่ใช่ค่าคงที่ เพียงระมัดระวังในการเปลี่ยนกลับเพิ่มเติมในโค้ดของคุณการกำหนดตัวแปรส่วนกลางใหม่อาจส่งผลกระทบต่อส่วนอื่น ๆ ของแอปพลิเคชันของคุณ


3
ที่จริงถ้าคุณต้องการที่จะเปลี่ยนเส้นทางออกคุณอาจจะใช้กระแสเอาท์พุทเริ่มต้นไม่ได้$> $stdout
Jörg W Mittag

10
เพิ่งพบความคิดเห็นในคำถามอื่นที่ระบุว่า$stdoutและ$>เป็นนามแฝงดังนั้นการกำหนดใหม่จะส่งผลต่ออีกคำถามหนึ่ง
jrdioko

9
@jrdioko: คุณพูดถูก เห็นได้ชัดว่าฉันไม่เพียง แต่เรียนรู้สิ่งใหม่ ๆ ทุกวันฉันยังลืมบางสิ่งบางอย่างทุกวัน :-)
Jörg W Mittag

2
และเมื่ออ่านเพิ่มเติมดูเหมือนว่าจะดีกว่าถ้าใช้IO # เปิดใหม่แทนการมอบหมายง่ายๆ
jrdioko

@jrdioko ทำไมคุณถึงคิดว่ามันจะดีกว่าที่จะใช้IO#reopenในกรณีของ$stdout? ฉันไม่เห็นด้วยกับความคิดเห็นนี้โดยสิ้นเชิง $stdout.reopenวิธีการแปรรูปและรับว่าจะมีผลต่อSTDOUTหากคุณไม่ได้มีพระราชเสาวนีย์$stdoutก่อน ไม่ได้หมายถึงคำพ้องความหมาย แต่ก็ไม่มีอะไรเลวร้ายเมื่อพวกเขามีค่าที่แตกต่างกันเนื่องจากการมอบหมายงานและโดยการเปิดขึ้นมาใหม่เมื่อSTDOUTคุณทำลายวัตถุประสงค์
skalee

5
  • STDOUT เป็นค่าคงที่ทั่วโลกดังนั้นจึงไม่ควรเปลี่ยนแปลง
  • $stdout เป็นตัวแปรที่กำหนดไว้ล่วงหน้าดังนั้นจึงสามารถเปลี่ยนแปลงได้

หากคุณใช้เชลล์ในการเปลี่ยนเส้นทาง:

$ ruby test.rb > test.log

ไม่สำคัญว่าคุณจะใช้ไฟล์ใดเป็นตัวอธิบายไฟล์สำหรับสคริปต์ของคุณก่อนที่สคริปต์ของคุณจะถูกเรียกใช้งาน

อย่างไรก็ตามหากคุณกำลังพยายามเปลี่ยน file descriptor สำหรับ STDOUT ของ OS จากภายในสคริปต์ Ruby ของคุณตัวอย่างเช่นเพื่อส่งเอาต์พุตไปยังชุดไฟล์บันทึกที่หมุนเวียนตามวันปัจจุบันของสัปดาห์คุณจะต้องแน่ใจว่า คุณใช้$stdout.


5
"STDOUT เป็นค่าคงที่ทั่วโลกดังนั้นจึงไม่มีการเปลี่ยนแปลง" เป็นค่าคงที่ซึ่งสามารถเปลี่ยนแปลงได้ แต่จะมีการออกคำเตือน STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
The Tin Man

อ่าใช่ควรพูดว่า "จึงไม่ควรเปลี่ยนแปลง" ขอบคุณ!
shakerlxxv

5

ทั้งสอง$stdoutและSTDOUTมีความหมายที่แตกต่างกัน เอกสารของ Rubyค่อนข้างชัดเจนในหัวข้อนี้:

  • $stdout - เอาต์พุตมาตรฐานปัจจุบัน
  • STDOUT- เอาต์พุตมาตรฐาน ค่าเริ่มต้นสำหรับ $ stdout

เมื่อคุณต้องการที่จะเขียนถึงมาตรฐานการส่งออกแล้วคุณจริงหมายถึงปัจจุบัน$stdoutออกมาตรฐานดังนั้นคุณควรจะเขียนถึง

STDOUTก็ไม่ไร้ประโยชน์เช่นกัน $stdoutมันเก็บค่าเริ่มต้นสำหรับ ถ้าคุณเคยโอนแล้วคุณสามารถเรียกคืนไปยังค่าก่อนหน้านี้ที่มี$stdout$stdout = STDOUT

นอกจากนี้ยังมีตัวแปรที่กำหนดไว้ล่วงหน้าอีกหนึ่งตัวแปร:

  • $>- เอาต์พุตเริ่มต้นสำหรับ print, printf ซึ่งเป็น$stdoutค่าเริ่มต้น

อย่างไรก็ตามดูเหมือนว่าใน Ruby 2.3 จะทำงานเป็นนามแฝงสำหรับ$stdout. การกำหนดใหม่$stdoutจะเปลี่ยนค่าของ$>และในทางกลับกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.