Ruby有两种引用标准输入的方法:STDIN
常量和$stdin
全局变量。
除了事实上,我可以在不同的IO
对象分配给$stdin
,因为它不是一个恒定的,什么是STDIN
和$stdin
之间的差异(例如分叉重定向IO在我的孩子之前)?什么时候应该在我的代码中使用每一个?
如果我重新分配$stdin
,它会影响STDIN
?
而这是否也适用于STDOUT
/$stdout
和STDER
/$stderr
?
Ruby有两种引用标准输入的方法:STDIN
常量和$stdin
全局变量。
除了事实上,我可以在不同的IO
对象分配给$stdin
,因为它不是一个恒定的,什么是STDIN
和$stdin
之间的差异(例如分叉重定向IO在我的孩子之前)?什么时候应该在我的代码中使用每一个?
如果我重新分配$stdin
,它会影响STDIN
?
而这是否也适用于STDOUT
/$stdout
和STDER
/$stderr
?
如果$stdin
被重新分配,STDIN
不受影响。同样$stdin
在STDIN
重新分配时不受影响(这是完全可能的(虽然毫无意义),但会产生警告)。但是,如果两个变量都没有重新分配,它们都指向相同的IO对象,因此在一个对象上调用reopen
¹会影响另一个对象。
所有内置ruby方法都使用$<
(又名ARGF
)来读取输入。如果ARGV
为空,则ARGF
从$stdin
中读取,因此如果您重新指定$stdin
,则会影响所有内置方法。如果您重新指定STDIN
,除非某些第三方方法使用STDIN
,否则它将不起作用。
在您自己的代码中,您应该使用$stdin
以与内置方法2保持一致。
¹reopen
是一种可以将IO对象重定向到另一个流或文件的方法。但是,您不能使用它将IO重定向到StringIO,因此它不会消除重新分配$stdin
的所有用例。
²你当然也可以使用$<
/ARGF
要与内置的方法更加一致,但大多数时候,你不如果你明确使用标准输入流所需的ARGF
行为。
我非常肯定内置方法使用`$ <`(默认输入流)和`$>`(默认输出流),也没有`$ stdin` /`STDIN`和`$ stdout` /`` STDOUT`。事实上,这几乎是'$ <` and `$>`的全部重点:您可以重定向方法的输入和输出,例如`Kernel#puts` *,而不影响stdin/stdout。 – 2010-11-26 12:10:13
STDERR和$ stderr最初指向相同的东西;你可以重新分配全局变量,但不应该混淆常量。 $ stdin和STDIN,$ stdout和STDOUT对同样如此。
我不得不改变STDERR几次,以替代猴子修补一些用STDERR.puts输出错误信息的宝石。如果你重新分配STDERR = $ stdout,你会得到一个警告,而STDERR.reopen('nul','w')不言而喻。
`$ stdin`是丑陋的。 – 2011-11-17 22:39:48