【问题标题】:What is the difference between STDIN and $stdin in Ruby?Ruby 中的 STDIN 和 $stdin 有什么区别?
【发布时间】:2011-05-15 20:13:08
【问题描述】:

Ruby 有两种引用标准输入的方式:STDIN 常量和 $stdin 全局变量。

除了我可以为 $stdin 分配一个不同的 IO 对象,因为它不是一个常量(例如,在我的孩子分叉重定向 IO 之前)之外,STDIN$stdin 之间有什么区别?我应该什么时候在我的代码中使用每个?

如果我重新分配$stdin,是否会影响STDIN

这是否也适用于STDOUT/$stdoutSTDER/$stderr

【问题讨论】:

    标签: ruby stdin


    【解决方案1】:

    STDERR 和 $stderr 最初指向同一个东西;你可以重新分配全局变量,但你不应该弄乱常量。 $stdin 和 STDIN,$stdout 和 STDOUT 对也是如此。

    我不得不更改 STDERR 几次,以替代猴子修补一些使用 STDERR.puts 输出错误消息的 gem。如果您使用 STDERR = $stdout 重新分配,则会收到警告,而 STDERR.reopen('nul', 'w') 不用说。

    【讨论】:

      【解决方案2】:

      如果$stdin 被重新分配,STDIN 不受影响。同样,$stdin 在重新分配 STDIN 时不会受到影响(这完全有可能(尽管毫无意义),但会产生警告)。但是,如果两个变量都没有被重新分配,它们都指向同一个 IO 对象,因此在一个上调用 reopen¹ 会影响另一个。

      所有内置的 ruby​​ 方法都使用$<(又名ARGF)来读取输入。如果ARGV 为空,则ARGF$stdin 读取,因此如果重新分配$stdin,这将影响所有内置方法。如果您重新分配 STDIN 它将无效,除非某些 3rd 方方法使用 STDIN

      在您自己的代码中,您应该使用$stdin 以与内置方法保持一致²。

      ¹reopen 是一种可以将 IO 对象重定向到另一个流或文件的方法。但是您不能使用它将 IO 重定向到 StringIO,因此它不会消除重新分配 $stdin 的所有用例。

      ²您当然也可以使用$</ARGF 来与内置方法更加一致,但大多数时候您想要ARGF如果您明确使用标准输入流,则行为。

      【讨论】:

      • 我很确定内置方法使用$<(默认输入流)和$>(默认输出流),既不是$stdin/STDIN也不是@987654344 @/STDOUT。事实上,这几乎就是$<$> 的全部意义所在:您可以重定向Kernel#puts 等方法的输入和输出, 不会影响stdin/stdout。
      • @Jörg:你说得对,他们使用$<$>,我会更正一下。但是您对第二点的看法不对:$>$stdout 是别名,因此重新分配一个会影响另一个(与不受影响的 STDOUT 不同)。 $<ARGF 相同,两者都不能重新分配。但是重新分配$stdin 影响$<ARGF,因为如果ARGV 为空,ARGF$stdin 读取。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      • 1970-01-01
      • 2014-06-14
      相关资源
      最近更新 更多