Різниця між $ stdout та STDOUT у Ruby


89

У Ruby, у чому різниця між $stdout(перед знаком долара) та STDOUT(у всіх великих літери)? Виконуючи переспрямування вихідних даних, що слід використовувати і чому? Те саме стосується $stderrі STDERR.

Редагувати: Щойно знайшов відповідне запитання .



@theTinMan Дещо це дублікат. Однак слід зазначити, що, хоча різниці між $stdoutі STDOUTпроти $stdinта STDINє симетричними, різниці між $stdoutта $>проти $stdinта $<не є.
skalee 03.03.16

Відповіді:


108

$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 # reopen замість простого призначення.
jrdioko

@jrdioko Чому, на вашу думку, краще використовувати IO#reopenу випадку $stdout? Я абсолютно не згоден з цією думкою. $stdout.reopenМетод мутує його приймач , і це буде впливати , STDOUTякщо ви не перепризначити $stdoutраніше. Вони не мають на меті бути синонімами, і нічого страшного немає, коли вони мають різні значення за призначенням, і, повторно відкривши те, STDOUTщо ви порушуєте, це мета.
skalee 03.03.16

5
  • STDOUT є глобальною константою, тому її не слід змінювати.
  • $stdout є заздалегідь визначеною змінною, тому її можна змінити.

Якщо ви використовуєте оболонку для перенаправлення:

$ ruby test.rb > test.log

тоді не має значення, який із них ви використовуєте як дескриптор файлу для вашого сценарію, визначається до того, як ваш скрипт буде виконаний.

Однак, якщо ви намагаєтесь змінити дескриптор файлу для STDOUT ОС із вашого сценарію Ruby, наприклад, щоб надіслати вихідні дані до обертового набору файлів журналів, заснованого на поточний день тижня, тоді вам потрібно буде переконатися ви використовуєте $stdout.


5
"STDOUT - це глобальна константа, тому вона не зміниться". Це константа, яку МОЖЕТЬ змінити, але буде видане попередження. STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
The Tin Man

Ах, так, так слід сказати "тому його не слід міняти". Дякую!
shakerlxxv

5

Обидва $stdoutі STDOUTмають різне значення. Документація Рубі досить чітка щодо цієї теми:

  • $stdout - Поточний стандартний вихід.
  • STDOUT- Стандартний вихід. Значення за замовчуванням для $ stdout.

Коли ви хочете написати на стандартний вихід, тоді ви маєте на увазі поточний стандартний вихід, тому вам слід писати на $stdout.

STDOUTтеж не марний. Він зберігає значення за замовчуванням для $stdout. Якщо ви коли-небудь перепризначили $stdout, то можете відновити його до попереднього значення за допомогою $stdout = STDOUT.

Крім того, є ще одна заздалегідь визначена змінна:

  • $>- Вивід за замовчуванням для друку printf, який є $stdoutза замовчуванням.

Однак схоже, що в Ruby 2.3 він просто поводиться як псевдонім для $stdout. Перепризначення $stdoutзмінює значення $>і навпаки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.