"test" irb(main):002:0> puts a test => nil -6ren">
gpt4 book ai didi

ruby - Ruby 是否使用 $stdout 来写入 puts 和 return 的输出?

转载 作者:数据小太阳 更新时间:2023-10-29 07:12:47 27 4
gpt4 key购买 nike

我想知道 Ruby 用来在命令行打印这些东西的输出流:

irb(main):001:0> a="test"
=> "test"
irb(main):002:0> puts a
test
=> nil
irb(main):003:0> a
=> "test"

$stdout 是否用于 irb(main):002:0>irb(main):003:0>?而且,在这两次调用之间,$stdout 的值是否有任何变化?

另外,有人能告诉我打印/写入这些内容的 Ruby 源代码吗?

最佳答案

是的。而且很容易向自己测试/证明。在命令行试试这个:

ruby -e 'puts "foo"' > test.out
cat test.out

输出将是:

foo

Ruby 使用 STDOUT channel 输出到控制台。然后操作系统将该 STDOUT 重定向到“test.out”。

试试看:

ruby -e 'STDOUT.puts "foo"' > test.out

你会得到相同的结果。

如果我们这样做:

ruby -e 'STDERR.puts "foo"' > test.out
foo
cat test.out

您不会在文件中看到任何内容,但“foo”将已写入 STDERR channel 上的控制台。

Ruby 将 $stdout 定义为您可以更改的全局变量,并将 STDOUT 定义为您不应更改的常量。同样,$stderrSTDERR 可用。

现在,这里是有趣的地方,并证明了您的问题。试试这个:

ruby -e '$stdout = STDERR; puts "foo"' > test.out

并且您将获得与我输出到 STDERR 时相同的结果,因为在 puts 处使用的是 $stdout 的值选择输出流,并写入 STDERR。当解释器启动时,Ruby 从操作系统中获取这些流值,并在脚本运行时记住这些值。您可以如有必要更改它们,Ruby 将在解释器退出时忘记这些设置,并在下次将其自身重置为正常状态。

不过,您不应该依赖于更改 $stdout 的隐含/不可见行为,因为这会导致代码非常困惑。相反,我强烈建议您在写入 STDERR 时使用显式 STDERR.puts,并使用裸露的 puts 以正常输出到 STDOUT。如果您将两者的输出混合在一起,那么使用 STDOUT.putsSTDERR.puts 可能会更清楚,但这是您的决定。

现在,就使用 $stdout 而言,IRB 与在解释器中运行的常规脚本相同,因此将 IRB 中的输出写入 $stdout 的工作方式相同:

irb(main):001:0> $stdout
#<IO:<STDOUT>>
irb(main):002:0> $stderr
#<IO:<STDERR>>

和:

irb(main):003:0> $stdout.puts 'foo'
foo
nil
irb(main):004:0> $stderr.puts 'foo'
foo
nil

最后:

irb(main):007:0> $stdout.isatty
true
irb(main):008:0> $stdout.isatty
true

除非我们往下看,否则我们无法真正分辨出任何区别;它们都是 TTY channel ,具有标准的 STDOUT 和 STDERR channel 号:

irb(main):009:0> $stdout.fileno
1
irb(main):010:0> $stderr.fileno
2

希望这有助于“解释它”。


我刚刚意识到 IRB 对 puts 返回值的报告可能会让您感到困惑,导致您认为 STDOUT 正在发生变化。返回的 nil 与 STDOUT 或 STDERR 无关。这是因为 puts 返回 nil,这是 IRB 尽职尽责的报告。

关于ruby - Ruby 是否使用 $stdout 来写入 puts 和 return 的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21343523/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com