Difference between `STDIN` and` $ stdin`
From Ruby globals :
STDIN
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.
source to share
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
originaly.
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).
source to share