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