【问题标题】:Difference between $stdout and STDOUT in RubyRuby 中 $stdout 和 STDOUT 的区别
【发布时间】:2011-10-04 01:02:39
【问题描述】:

在 Ruby 中,$stdout(前面有一个美元符号)和STDOUT(全部大写)有什么区别?在进行输出重定向时,应该使用哪个,为什么? $stderrSTDERR 也是如此。

编辑:刚刚找到related question

【问题讨论】:

标签: ruby stdout stderr output-redirect


【解决方案1】:

$stdout 是一个代表当前标准输出的全局变量STDOUT 是一个代表标准输出的常量,通常是$stdout 的默认值。

STDOUT 是一个常量,您不应该重新定义它,但是,您可以重新定义 $stdout 而不会出现错误/警告(重新定义 STDOUT 会引发警告)。例如,你可以这样做:

$stdout = STDERR

$stderrSTDERR 也是如此


因此,要回答您问题的另一部分,请使用全局变量而不是常量来重定向输出。请注意在您的代码中进一步更改它,重新定义全局变量可能会影响应用程序的其他部分。

【讨论】:

  • 其实,如果你想重定向输出,你可能应该使用默认输出流$>,而不是$stdout
  • 刚找到一个comment on another question,上面写着$stdout$> 是别名,所以重新分配一个会影响另一个。
  • @jrdioko:你是对的。显然,我不仅每天都学到新东西,而且每天都会忘记一些东西:-)
  • 而且阅读更多,听起来最好使用IO#reopen 而不是简单的赋值。
  • @jrdioko 为什么你认为在$stdout 的情况下使用IO#reopen 更好?我完全不同意这种观点。 $stdout.reopen 方法 mutates 它的接收者,如果您之前没有重新分配 $stdout,这也会影响 STDOUT。它们并不意味着是同义词,当它们由于分配而持有不同的值时并没有什么不好,并且通过重新打开 STDOUT 你打破了它的目的。
【解决方案2】:
  • STDOUT 是一个全局常量,因此不应更改。
  • $stdout 是预定义变量,因此可以更改。

如果你使用shell做重定向:

$ ruby test.rb > test.log

那么在你的脚本执行之前,你使用哪一个作为脚本的文件描述符并不重要。

但是,如果您尝试在 Ruby 脚本中更改操作系统 STDOUT 的文件描述符,例如根据一周中的当前日期将输出发送到一组轮换的日志文件,那么您需要确保您使用$stdout

【讨论】:

  • “STDOUT 是一个全局常量,所以它不会改变”。它是一个常数,可以更改,但会发出警告。 STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
  • 啊,是的,所以应该说“所以不应该改变”。谢谢!
【解决方案3】:

$stdoutSTDOUT 有不同的含义。 Ruby's documentation 非常清楚这个话题:

  • $stdout – 当前标准输出。
  • STDOUT – 标准输出。 $stdout 的默认值。

当您要写入标准输出时,您实际上是指当前标准输出,因此您应该写入$stdout

STDOUT 也不是没用的。它存储$stdout 的默认值。如果您曾经重新分配 $stdout,那么您可以使用 $stdout = STDOUT 将其恢复为之前的值。

此外,还有一个预定义变量:

  • $> - print 的默认输出 printf,默认为 $stdout

然而它在 Ruby 2.3 中看起来只是作为$stdout 的别名。重新分配 $stdout 会更改 $> 的值,反之亦然。

【讨论】:

    猜你喜欢
    • 2012-03-25
    • 2012-10-05
    • 2020-05-13
    • 2015-07-31
    • 2015-08-27
    • 2023-03-31
    • 2015-06-20
    • 2020-01-24
    • 2011-10-30
    相关资源
    最近更新 更多