When opening a file in perl, how can I automatically use STDIN / OUT if the file name is "-"?

I have a perl program that accepts the input and output arguments of a file, and I would like to support a "-" convention for specifying standard input / output. The problem is that I cannot just open the file name because open(my $input, '<', '-') opens a file with the name - rather than standard input. So I have to do something like this:

 my $input_fh; if ($input_filename eq '-') { # Special case: get the stdin handle $input_fh = *STDIN{IO}; } else { # Standard case: open the file open($input_fh, '<', $input_filename); } 

And similarly for the output file. Is there a way to do this without testing for a particular case? I know that I could crack the file descriptor ARGV to do this for input, but this will not work for output.

Edit: I was informed that the 2-argument form of open really does the magic I'm looking for. Unfortunately, he also does some creative interpretation to separate the file name from the mode in the second argument. I think the form of the 3-argument open is 100% free of magic - it always opens the exact file that you tell it. I ask if I can have a single exception for "-" , but still handle every other file name explicitly.

Should I just keep my code on top of the subprogram / module and stop whining?

+4
source share
2 answers

Instead, use a form with two arguments:

 open ($input_fh, "< " . $input_filename); 

From man perlfunc :

In the form of 2 arguments (and 1 argument), the opening "'-'" STDIN opens and the opening "'> -'" opens STDOUT.

Note that the < mode is optional in the form of 2 arguments, so "< -" is completely legal.

+4
source

I think I found what I was looking for. There's a great module called IO::All that does what I want and much more.

For Debian / Ubuntu / similar users, the package is called libio-all-perl . I wanted to make this link with the ability to click "apt: libio-all-perl", but apparently only http links are allowed here.


Edit

There's also an Iterator::Diamond that implements the custom magic that I ask for. It is intended to replace the "diamond" <> operator, but it will probably do what I ask if it is called by only one file (presumably with some overhead, but who needs it?).

0
source

Source: https://habr.com/ru/post/1306162/


All Articles