Ruby 中 $stdout 和 STDOUT 的区别

Posted

技术标签:

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

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

编辑:刚刚找到related question。

【问题讨论】:

What is the difference between STDIN and $stdin in Ruby?的可能重复 @theTinMan 有点重复。但是必须注意,虽然$stdoutSTDOUT$stdinSTDIN 之间的差异是对称的,但$stdout$>$stdin$< 之间的差异不是。 【参考方案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 会更改 $> 的值,反之亦然。

【讨论】:

以上是关于Ruby 中 $stdout 和 STDOUT 的区别的主要内容,如果未能解决你的问题,请参考以下文章

ruby 在RSpec中测试STDOUT 3

ruby stream system命令输出到STDOUT(ruby)

如何在 Ruby 中将 IO 对象转换为字符串?

stdin和stdout变量的意义

使用 Autohotkey 读取 StdErr 和 StdOut

stderr和stdout的区别