SuperManEver
SuperManEver

Reputation: 2362

Difference between `STDIN` and `$stdin`

I wonder if there is any real difference between STDIN and $stdin. I do in irb:

STDIN == $stdin

and get back true. Are they just two names for the same thing? Or is there some difference?

Upvotes: 3

Views: 335

Answers (2)

Petr Skocik
Petr Skocik

Reputation: 60058

STDIN is a constant and therefore you'll get a ruby warning if you try to replace it. Otherwise the two are just normal ruby variables in that they can point to the same object (and are by default) and if they do, doing something with one will affect the other variable, but if you assign something else to one of the variables, they will be different.

Standard ruby methods like get will read from $stdin (not STDIN) by default. That means you can override $stdin ($stdout, $stderr) for standard methods and use the constant versions to see what $stdin, $stdout or $stderr originaly were.

Note that overriding $stdin, $stdout, or $stderr won't affect the standard streams of newly spawned programs (the actual filedescriptors 0, 1, and 2 respectively). To do that you'd need to call IO#reopen on the stream you'd want to change, e.g. (assuming the constant version hasn't been forcibly replaced),

STDOUT.reopen("newfile") #Write all output to "newfile" including the output of newly spawned processes (`%x{}`,`system`, `spawn`, `IO.popen`, etc.)

Now with reopen, you can replace the streams only to actual OS-level files/file descriptors (e.g., no StringIO), but if you're on UNIX, there's not much you can't do with OS-level files (you can change them to pipes which you can read elsewhere in your program, for example).

Upvotes: 3

Arie Xiao
Arie Xiao

Reputation: 14082

From Ruby globals:

STDIN

The standard input. The default value for $stdin.

They are the same object by default.

[1] pry(main)> $stdin.object_id
=> 13338048
[2] pry(main)> STDIN.object_id
=> 13338048
[3] pry(main)> $stdin.object_id == STDIN.object_id
=> true

As @shivam commented, $stdin is a global variable and it may be assigned to something different, while STDIN is a constant.

Upvotes: 4

Related Questions