В чем разница между STDIN и $ stdin в Ruby? - PullRequest
36 голосов
/ 25 ноября 2010

В Ruby есть два способа обращения к стандартному вводу: константа STDIN и глобальная переменная $stdin.

Помимо того, что я могу назначить другой объект IO для $stdin потому что это не константа (например, перед тем, как разветвляться для перенаправления ввода-вывода у моих детей), в чем разница между STDIN и $stdin?Когда я должен использовать каждый из них в своем коде?

Если я переназначу $stdin, это влияет на STDIN?

И это также относится к STDOUT / $stdout и STDER / $stderr

Ответы [ 2 ]

39 голосов
/ 25 ноября 2010

Если $stdin переназначен, на STDIN это не влияет.Аналогично, на $stdin не влияет, когда STDIN переназначается (что вполне возможно (хотя и бессмысленно), но выдаст предупреждение).Однако, если ни одна из переменных не была переназначена, они обе указывают на один и тот же объект ввода-вывода, поэтому вызов reopen ¹ для одного из них повлияет на другой.

Все встроенные методы ruby ​​используют $< (иначе ARGF) для чтения ввода.Если ARGV пусто, ARGF читает из $stdin, поэтому, если вы переназначите $stdin, это повлияет на все встроенные методы.Если вы переназначите STDIN, это не будет иметь эффекта, если какой-либо сторонний метод не использует STDIN.

. В вашем собственном коде вы должны использовать $stdin, чтобы соответствовать встроенным методам².

¹ reopen - это метод, который может перенаправить объект ввода-вывода в другой поток или файл.Однако вы не можете использовать его для перенаправления ввода-вывода в StringIO, поэтому он не исключает все случаи переназначения $stdin.

² Конечно, вы также можете использовать $< / ARGF длябудьте еще более совместимы со встроенными методами, но большую часть времени вы не хотите использовать поведение ARGF, если вы явно используете поток stdin.

1 голос
/ 25 ноября 2010

STDERR и $ stderr изначально указывают на одно и то же; Вы можете переназначить глобальную переменную, но не следует связываться с константой. Пары $ stdin и STDIN, $ stdout и STDOUT аналогичны.

Мне пришлось пару раз менять STDERR в качестве альтернативы мартовскому исправлению некоторых драгоценных камней, выводящих сообщения об ошибках с помощью STDERR.puts. Если вы переназначаете STDERR = $ stdout, вы получите предупреждение, тогда как STDERR.reopen ('nul', 'w'), само собой разумеется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...