PERL CLOSING the file after slurping and "perl -0777"s translation to a complete perl file

Viewed 215

Inspired by the following perl one-liner perl -0777 -ne 'while(m/YOUR_REGEX_HERE/g){print "$&\n";}' YOUR_FILE_HERE, I am searching for the simplest way to read an entire file into a string (a procedure also known as “slurping”) in a complete perl file (not just a perl command), as I need to do simple operations using two files. I came around this: https://www.perl.com/article/21/2013/4/21/Read-an-entire-file-into-a-string/. (I am looking at Slurping files without modules.)

It suggests using

open my $fh, '<', 'text_document.txt' or die "Can't open file $!";
read $fh, my $file_content, -s $fh;

But how do I close the file after processing it? (1)

Also, how would that one-liner translate to a perl file, not just a perl command? (2)

Thank you!

2 Answers

You can change the line ending special variable to be nothing within a block to keep it local. It'll be restored to the local platform's record separator after the block ends:

use warnings;
use strict;

my $contents;

{
    local $/;
    open my $fh, '<', 'file.txt' or die $!;
    $contents = <$fh>;
    close $fh;
}

print $contents;

Note that the bare block in the above code could be substituted with a subroutine instead.

If you want it compact, on one line:

my $file_content = do { local (@ARGV, $/) = $file_name; <> };

The <> "null" filehandle opens and reads all files with names in @ARGV special variable. We add $file_name to @ARGV but only after this global variable is local-ized, so that whatever may have been in the array is saved away and then restored once control leaves this block. Thus <> reads the whole file, and since it is the last command in the do block what it read is returned.

In order to read the whole file into a string ("slurp" it) we unset the $/ special variable ("input record separator"), also after it is local-ized of course.

Related