【发布时间】:2015-04-22 22:14:15
【问题描述】:
我想知道STDIN 和$stdin 之间是否有任何真正的区别。我在 irb 做:
STDIN == $stdin
然后返回true。它们只是同一事物的两个名称吗?还是有什么不同?
【问题讨论】:
标签: ruby
我想知道STDIN 和$stdin 之间是否有任何真正的区别。我在 irb 做:
STDIN == $stdin
然后返回true。它们只是同一事物的两个名称吗?还是有什么不同?
【问题讨论】:
标签: ruby
来自Ruby globals:
标准输入
标准输入。 $stdin 的默认值。
默认情况下它们是同一个对象。
[1] pry(main)> $stdin.object_id
=> 13338048
[2] pry(main)> STDIN.object_id
=> 13338048
[3] pry(main)> $stdin.object_id == STDIN.object_id
=> true
正如@shivam 评论的那样,$stdin 是一个全局变量,它可能被分配给不同的东西,而STDIN 是一个常量。
【讨论】:
$stdin = "asd", $stdin.object_id == STDIN.object_id # => false
puts、gets 默认使用的输入和输出的方法。
STDIN 是一个常量,因此如果您尝试替换它,您会收到一个红宝石警告。否则,这两个只是普通的 ruby 变量,因为它们可以指向同一个对象(并且默认情况下),如果它们这样做,对一个变量做某事会影响另一个变量,但是如果你将其他东西分配给其中一个变量,它们会有所不同。
默认情况下,get 等标准 ruby 方法将从 $stdin(不是 STDIN)读取。这意味着您可以为标准方法覆盖 $stdin($stdout、$stderr),并使用常量版本来查看 $stdin、$stdout 或 $stderr 原来是什么。
请注意,覆盖 $stdin、$stdout 或 $stderr 不会影响新生成程序的标准流(实际文件描述符分别为 0、1 和 2)。为此,您需要在要更改的流上调用 IO#reopen,例如(假设常量版本没有被强制替换),
STDOUT.reopen("newfile") #Write all output to "newfile" including the output of newly spawned processes (`%x{}`,`system`, `spawn`, `IO.popen`, etc.)
现在通过重新打开,您只能将流替换为实际的操作系统级别的文件/文件描述符(例如,没有 StringIO),但如果您使用的是 UNIX,那么您可以使用操作系统做的事情不多 -级别文件(例如,您可以将它们更改为可以在程序的其他地方读取的管道)。
【讨论】: