Open a scalar as a file in Perl
Asked Answered
C

1

5

According to PerlDoc you can direct a file open to a scalar variable https://perldoc.perl.org/functions/open#Opening-a-filehandle-into-an-in-memory-scalar

I am trying to establish if I can use this approach for a temp file that is persistent within the lexical domain. I am doing the following as a test:

my $memfile;
my $filename=\$memfile;

open (OUT, ">", $filename);
print OUT "some data\n";
close (OUT);

I want to be able to read from the scalar later; eg:

open (IN, "<", $filename);
while (my $in=<IN>)
{
  print "$in\n";
}
close (IN);

This doesn't work, so am I barking mad or is there a right way to do it so it does work?

Carhart answered 23/1, 2023 at 20:44 Comment(6)
perl -wE'open my $fh, ">", \my $mem or die $!; say $fh "hi"; say "var: $mem"' works finePetrie
Or, if you insist on another layer of variables (why that?), perl -wE'my $mem; my $f = \$mem; open my $fh, ">", $f or die $!; say $fh "hi"; say "var: $mem"' works as wellPetrie
I made a typo on my actual test code and now I fixe dit, it works. I feel so dumb now.Carhart
"typo on my actual test code" -- ok, no dumb, happens all the time to everybody :)Petrie
"use this approach for a temp file that is persistent within the lexical domain." --- btw, what do you mean by "persistent" and by "lexical domain"? That the file itself exists while in the scope and is gone once that scope is left? Perhaps look into File::Temp?Petrie
Also asked in /r/perl. It's fine to crosspost but tell people you are doing that so they don't spend time answering a question that already has an answer.Egghead
P
7

We can indeed open a filehandle to a variable, and write to it; and then we can use it like any other variable

open my $fhv, '>', \my $memfile or die $!;
say $fhv "hi";
close $fhv;

print $memfile;  # hi\n

One can also open a filehandle to the variable's reference for reading, like in the question, but this usually isn't needed. (A possible use would be if we want to keep writing and reading such that it can be changed between file/variable merely by changing the open statement.)

This works with another "layer" of variables, like in the question, as well,

 my $memfile;
 my $file = \$memfile;
 open my $fhv, '>', $file or die $!;
 say $fhv "hi";
 close $fhv;

 print $memfile;

Can again open a filehandle to $file for reading, as well.

Note that $fhv isn't quite a proper filehandle and some filehandle-uses will not work; see this page for one example.

Petrie answered 23/1, 2023 at 21:0 Comment(3)
It turns out I made a typo in my test code and of course it works when I fixed it. I feel so dumb right now.Carhart
Alright, it happens :). Btw, if you need more advanced and flexible (etc) ways to read/write from/to resources try out IPC::Run. It supports all kinds of thingsPetrie
@Carhart Edited a little; nothing dramatic but you may want to take a glancePetrie

© 2022 - 2024 — McMap. All rights reserved.