Difference between `STDIN` and` $ stdin`

I wonder if there is any real difference between STDIN

and $stdin

. I do in irb:

STDIN == $stdin


and go back true

. Are they just two names for the same thing? Or is there a difference?


source to share

2 answers

From Ruby globals :


Standard input. Default value for $ stdin.

By default, they are the same object.

[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 pointed out, $stdin

is a global variable and it can be assigned something else, but STDIN

is a constant.



STDIN is constant, so you'll get a ruby ​​warning if you try to replace it. Otherwise two are just normal ruby ​​variables as they can point to the same object (and by default), and if they do, then something with one affects the other variable, but if you assign something another variable, they will be different.

Standard ruby ​​methods such as get

will read from $stdin

(not STDIN) by default. This means that you can override $stdin

( $stdout

, $stderr

) for standard methods and use constant versions to see what was $stdin

, $stdout

or $stderr


Note that overriding $stdin

, $stdout

or $stderr

will not affect the standard streams of newly created programs (actual filedescriptors 0, 1, and 2, respectively). To do this, you need to call IO#reopen

on the thread you want to change, eg. (assuming the permanent version has not been forcefully replaced)

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


Now on reopening you can replace streams with only actual OS level files / file descriptors (e.g. no StringIO

), but if you are on UNIX you cannot do anything with OS- (you can change them to pipes you can read in elsewhere in your program, for example).



All Articles