in reply to removing the need for tmp files from script

Another option is to change your open statement so the filehandle of your temp file refers to an "in-memory" file. No other changes are required. Temporary data would go to a scalar instead of a disk. Refer to 'open' in perlfunc for more on in-memory files.
Bill
  • Comment on Re: removing the need for tmp files from script

Replies are listed 'Best First'.
Re^2: removing the need for tmp files from script
by novice2015 (Acolyte) on Jul 25, 2016 at 21:59 UTC
    Fantastic information. I was wondering though, you don't seem to be able to use the "filehandle" variable like a real file in a script. For example: I have this beginnerish script
    open my $fh2, '<', '/tmp/mlist.txt' or die "unable to open file '$file +' for reading : $!"; open my $fh9, '>', '/tmp/listk.txt' or die "unable to open file '$file +' for reading : $!"; while (<$fh2>) { my @fields = split(',', $_); local $" = ','; if ($fields[2] eq '1' || $fields[2] eq '0') { print $fh9 "@fields[4]\n" if /MONTHLY/ && !/,-,/; } } close $fh2; close $fh9;
    This is clumsy but it works. However, if I try to use the variable assigned to a filehandle in the same way:
    open my $bpfh1, '<', \$forbpjoutput or die $!; while (<$bpfh1>) { my @fields = split(',', $_); my $fields; local $" = ','; if ($fields[2] eq '1' ||$fields[2] eq '0') { print "THESE ARE THE>>> $fields[4]\n" if /MONTHLY/ && !/, +-,/; close $bpfh1; } }
    it does work but what happens is that it never stops printing the "file" or the fields4 It continues until out of memory. Is there a way to do this differently? This is probably a very basic question, but I don't have much experience with filehandles which are variables.
      Hi novice2015

      The link to open that BillKSmith mentioned in his post has the following text.

      # in-memory files 21. open(my $memory, ">", \$var) 22. or die "Can't open memory file: $!"; 23. print $memory "foo!\n"; # output will appear in $var
      This shows how to write to an in-memory file.

      To read from an in memory file, you would do this:

      #!/usr/bin/perl use strict; use warnings; my $file = 'here are some words I want '; open my $fh, '<', \$file; chomp(my @words = <$fh>); my $pattern = join "|", @words; print $pattern;
      That would be a way to not need the tmp. file.
        this works great. However, I have one issue in that the file has 2 lines in it and only the first line gets printed.
        my $pattern = join '|', @words; my $forx; open my $bpfh1, '>', \$forx or die $!; for (@bpj) { print $bpfh1 "$_\n", $_ if /$pattern/; } open my $bpfh1, '<', \$forx or die $!; while (<$bpfh1>) { my @fields = split(',', $_); my $fields; local $" = ','; if ($fields[2] eq '1' ||$fields[2] eq '0') { print "THESE ARE THE>>$fields[4]\n" if /MONTHLY/ && !/,-, +/; } close $bpfh1; } close $bpfh1; }
        So what I get is LISTING-INVENTORY-CATALOG LISTING-PURCHASING-CATALOG The variable (memory file) $forx does contain data, and it prints out just fine. But only the first line. I have tried different things to make the second line print, such as closing the file earlier, but it doesn't work. I've had this problem before but can't remember how I got it resolved. Any ideas?
      I cannot duplicate your problem. When I run your code on my system (perl v5.20.2 on Windows 10), it terminates with no error messages and no output. It I use warnings, I get several copies of a warning about uninitialized value in $bpfh1. If I declare $forbpjoutput as a lexical variable and define it as a null string, I get no messages and no output even using strict and warnings. (This is exactly what I expect).
      use strict; use warnings; my $forbpjoutput = q(); open my $bpfh1, '<', \$forbpjoutput or die $!; ... # Exactly as in your post.

      As Cristoforo pointed out, you probably did not intend to input from a null file. I cannot guess what you really did intend to do.

      Bill