Re: Override "null filehandle"
by choroba (Cardinal) on Sep 04, 2023 at 06:42 UTC
|
The diamond operator reads from ARGV, not STDIN.
open my $INPUT, '<', \"my input\n";
*ARGV = $INPUT;
print <>;
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
|
% echo This is from STDIN|perl -e'print for <>'
This is from STDIN
% echo This is from ARGV > input1
% echo This is also from ARGV > input2
% perl -e'print for <>' input1 input2
This is from ARGV
This is also from ARGV
The <> operator looks first at at @ARGV and iterates line by line through each file specified as arguments to the script. But if there are no arguments (@ARGV is empty) then it falls back to reading from STDIN. This behaviour is documented in perlop, already linked to by the OP. | [reply] [d/l] |
|
|
The diamond operator reads from ARGV, not STDIN.
That's not quite true
choroba is correct though, in that <> is always equivalent to <ARGV>, as is described in the very documentation you referenced. The magical behavior you describe is not that of the <> operator in general, it is that of the ARGV filehandle, which modifies @ARGV in order for STDIN to be read automatically via the ARGV handle.
Reworded for clarity, shortly after posting.
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
Re: Override "null filehandle"
by haukex (Archbishop) on Sep 04, 2023 at 10:54 UTC
|
in this case, the input from <> comes from "standard input". If this were exactly the same thing as "STDIN"
As per perlop and choroba's reply, <> is the same as <ARGV>.
Is there a way to override the "null filehandle" ?
That depends a bit on what you want to accomplish, could you describe that?* You've already gotten some replies on how to do this for a couple of cases, and I just wanted to add that messing with ARGV even more is possible, as I did in my module Tie::Handle::Argv. However, because of all of the trouble I had writing and testing that module, I can say that this is a pretty complicated thing to do, and I would not mess with <> if it can be avoided. Therefore your sample code makes me a bit nervous that you might be trying to do something that's not really advisable.
* So for example, if you just want to mock <> for testing, it's better to do that by calling your script from another script and feeding it stuff to its STDIN, which can be done reliably, or just by placing test files (e.g. generated via File::Temp) in its @ARGV (Update: for example, you can localize *ARGV - yes, the whole typeglob).
| [reply] [d/l] [select] |
Re: Override "null filehandle"
by tybalt89 (Monsignor) on Sep 04, 2023 at 02:37 UTC
|
#!/usr/bin/perl
use strict; # https://www.perlmonks.org/?node_id=11154231
use warnings;
use autodie;
close STDIN;
open STDIN, '<', \"my input\n";
print <>;
| [reply] [d/l] |
Re: Override "null filehandle"
by LanX (Saint) on Sep 04, 2023 at 00:29 UTC
|
From the docs you linked to:
> Here's how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input.
So what's happening is that STDIN is re-opened.
Did you try @ARGV = ($INPUT); instead?
update
just tested, doesn't work, this will try to use $INPUT as filename not handle...
From the proposed alternatives, I like choroba's best with *ARGV = \$INPUT
| [reply] [d/l] [select] |
Re: Override "null filehandle"
by BillKSmith (Monsignor) on Sep 06, 2023 at 14:14 UTC
|
Thanks for all your replies. I believe that any one of them would have solved my problem. A few days ago I wanted to include code in my post Re^2: Why is my code producing weird output?. That code would have made no changes to the OP's code except to add input that explicitly showed the windows line endings. That would have duplicated his problem. Adding binmode STDIN, ':crlf'; would have fixed it. When I could not make the demo work, I settled for the verbal reply. Only later did I think to ask how I might have done it.
Had I known all your answers, I probably would have chosen to close and reopen STDIN because it best describes my intention.
| [reply] [d/l] |