Ruby有两种引用标准输入的方法:STDIN
常量和$stdin
全局变量。
除了我可以为IO
分配不同的$stdin
对象这一事实,因为它不是常数(例如在我的孩子中重新定向IO之前),{{1}之间有什么区别?和STDIN
?我什么时候应该在我的代码中使用每个?
如果我重新分配$stdin
,是否会影响$stdin
?
这是否也适用于STDIN
/ STDOUT
和$stdout
/ STDER
?
答案 0 :(得分:38)
如果重新分配$stdin
,STDIN
不会受到影响。同样,$stdin
在重新分配STDIN
时不会受到影响(这完全可能(尽管毫无意义),但会产生警告)。但是,如果两个变量都没有被重新分配,它们都指向同一个IO对象,因此在一个上调用reopen
¹会影响另一个。
所有内置的ruby方法都使用$<
(a.k.a。ARGF
)来读取输入。如果ARGV
为空,则ARGF
会从$stdin
读取,因此如果您重新分配$stdin
,则会影响所有内置方法。如果您重新分配STDIN
,除非某些第三方方法使用STDIN
,否则它将无效。
在您自己的代码中,您应该使用$stdin
与内置方法2保持一致。
¹reopen
是一种可以将IO对象重定向到另一个流或文件的方法。但是,您无法使用它将IO重定向到StringIO,因此它不会消除重新分配$stdin
的所有用例。
²您当然也可以使用$<
/ ARGF
与内置方法更加一致,但大部分时间不想要如果您明确使用stdin流,则为ARGF
行为。
答案 1 :(得分:1)
STDERR和$ stderr最初指的是同一件事;你可以重新分配全局变量,但你不应该混淆常量。 $ stdin和STDIN,$ stdout和STDOUT对同样如此。
我不得不多次更改STDERR,以替代使用STDERR.puts输出错误消息的猴子修补程序。如果你用STDERR = $ stdout重新分配,你会收到一个警告,而STDERR.reopen('nul','w')则不用说。