Rubyには、標準入力を参照する2つの方法があります。STDIN
定数と、$stdin
グローバル変数です。
別のIO
オブジェクトを$stdin
に割り当てることができるという事実は別として、定数ではないため(たとえば、リダイレクトをフォークする前にIO私の子供たち))、 STDIN
と$stdin
の違いは?コードでそれぞれをいつ使用する必要があるのですか?
$stdin
を再割り当てした場合、STDIN
に影響しますか?
そして、これはSTDOUT
/$stdout
とSTDER
/$stderr
にも当てはまりますか?
_$stdin
_が再割り当てされても、STDIN
は影響を受けません。同様に、_$stdin
_は、STDIN
が再割り当てされても影響を受けません(これは完全に可能ですが(無意味ですが)、警告が表示されます)。ただし、どちらの変数も再割り当てされていない場合は、両方が同じIOオブジェクトを指しているため、一方でreopen
¹を呼び出すと、もう一方に影響します。
すべての組み込みRubyメソッドは_$<
_(別名ARGF
)を使用して入力を読み取ります。ARGV
が空の場合、ARGF
は_$stdin
_から読み取るため、_$stdin
_、これはすべての組み込みメソッドに影響します。STDIN
を再割り当てした場合、サードパーティのメソッドがSTDIN
を使用しない限り、効果はありません。
独自のコードでは、組み込みのメソッド²と一貫性を保つために_$stdin
_を使用する必要があります。
¹reopen
は、IOオブジェクトを別のストリームまたはファイルにリダイレクトできるメソッドです。ただし、これを使用してIOをStringIOにリダイレクトすることはできません。したがって、_$stdin
_を再割り当てするすべてのユースケースが排除されるわけではありません。
²もちろん、組み込みメソッドとの一貫性をさらに高めるために_$<
_/ARGF
を使用することもできますが、ほとんどの場合、しないでくださいARGF
の動作が必要です。 stdinストリームを明示的に使用します。
STDERRと$ stderrは、最初は同じものを指しています。グローバル変数を再割り当てすることはできますが、定数をいじってはいけません。 $ stdinとSTDIN、$ stdoutとSTDOUTのペアも同様です。
STDERR.putsでエラーメッセージを出力するいくつかのgemにモンキーパッチを適用する代わりに、STDERRを数回変更する必要がありました。 STDERR = $ stdoutで再割り当てすると、STDERR.reopen( 'nul'、 'w')が言うまでもなく警告が表示されます。