Ответ 1
Если $stdin
переназначается, STDIN
не влияет. Аналогично $stdin
не изменяется, когда STDIN
переназначается (что вполне возможно (хотя и бессмысленно), но выдает предупреждение). Однако, если ни одна переменная не была переназначена, они оба указывают на один и тот же объект ввода-вывода, поэтому вызов reopen
¹ на одном влияет на другой.
Все встроенные методы ruby используют $<
(a.k.a. ARGF
) для чтения ввода. Если ARGV
пусто, ARGF
читается из $stdin
, поэтому, если вы переназначаете $stdin
, это повлияет на все встроенные методы. Если вы переназначаете STDIN
, это не будет иметь эффекта, если какой-либо сторонний метод использует STDIN
.
В вашем собственном коде вы должны использовать $stdin
, чтобы он соответствовал встроенным методам².
¹ reopen
- это метод, который может перенаправлять объект IO на другой поток или файл. Однако вы не можете использовать его для перенаправления ввода-вывода в StringIO, поэтому он не устраняет все случаи использования переназначения $stdin
.
² Вы можете, конечно, также использовать $<
/ARGF
, чтобы быть более совместимым со встроенными методами, но большую часть времени вы не хотите поведения ARGF
, если вы явно используете поток stdin.