Ruby使用$ stdout写入puts和return的输出吗?

我想知道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源代码?

是。 并且很容易测试/certificate自己。 在命令行尝试此操作:

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

输出将是:

 foo 

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

尝试使用:

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

你会得到相同的结果。

如果我们这样做:

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

您将在文件中看不到任何内容,但“foo”将被写入STDERR频道的控制台。

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

现在,这里有趣,并certificate了你的问题。 试试这个:

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

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

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

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

 irb(main):001:0> $stdout #> irb(main):002:0> $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频道,标准的STDOUT和STDERR频道号码:

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

希望这有助于’摒弃它。


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

发生这种情况的原因是因为IRB在每次操作后调用对象。

有关详细信息,请参阅Object#inspect:

http://ruby-doc.org/core-2.1.0/Object.html#method-i-inspect

我们可以通过覆盖检查来certificate这一点:

  ~ $ irb >> class Foo >> def inspect >> 'hi' >> end >> end => nil >> foo = Foo.new => hi 

在你的情况下唯一触及$ stdout的是你的puts命令的结果。

希望这可以帮助!