ady has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

There's a pattern to the open and close statements in the code snippet below.
Could i collapse each pair (open, close) to ONE statement, like :
foreach ...

Or would that get too convoluted.

open (FH, "<${file}.txt") or die "Can't open ${file}.txt: $!\n"; open (FH1, ">${file}1.txt") or die "Can't open ${file}1.txt: $!\n"; while (<FH>) { ...do stuff with $_... } close (FH) or die "Can't close ${file}.txt: $!\n"; close (FH1) or die "Can't close ${file}1.txt: $!\n";

As the eternal tranquility of Truth reveals itself to us, this very place is the Land of Lotuses -- Hakuin Ekaku Zenji

Replies are listed 'Best First'.
Re: Collapsing multiple file open/close
by ikegami (Patriarch) on Apr 13, 2005 at 16:17 UTC

    The snippet doesn't compress nicely. Now, if you had more repetition, we might be able to do something. If this is just a sample of your code and you have more repetitiion in your real code, can you show it to us? I can't predict how this code would expand.

    You could let Perl close the handles for you:

    { local *FH; open(FH, "< ${file}.txt") or die "Can't open ${file}. +txt: $!\n"; local *FH1; open(FH1, "> ${file}1.txt") or die "Can't create ${file +}1.txt: $!\n"; while(<FH>) { print FH1 $_; } }

    or in newer versions of Perl:

    { open(my $fh, '<', "${file}.txt") or die "Can't open ${file}.txt: +$!\n"; open(my $fh1, '>', "${file}1.txt") or die "Can't create ${file}1.tx +t: $!\n"; while (<$fh>) { print $fh1 $_; } }

    But here is the answer to the question you asked. As I've said, it's not very useful.

    my @file_data = ( [ undef, "${file}.txt", 'r' ], [ undef, "${file}1.txt", 'w' ], ); foreach (@file_data) { my $name = $_->[1]; my $mode = $_->[2]; $_->[0] = IO::File->new($name, $mode) or die("Can't " . ($mode eq 'w' ? 'create' : 'open') . " file $name +: $!\n"); } while (<$file_data[0][0]>) { print $file_data[1][0] $_; } close($_->[0]) foreach @file_data;
      Rightoh!
      Yes, i like the auto-close solution here!
      What i was probing was something like :
      foreach my $i ("" "1") { open (FH$i, "<${file}$i.txt") or die "${file}$i.txt"; }

      but of course file handle names don't work that way.

      I like your general "foreach solution" too, but, yes, that's overkill for this specific snippet.
      Thanks for lightening up my understanding
      best regards, allan

        There are two problems with that:

        1) Creating symbols dynamically (FH$i) is pretty bad. I think you could use $FH{$i} instead (since Perl 5.6?), but your loop would become
        while (<$FH{''}>) { print $FH{1} $_; }

        2) You're opening both files for reading.

A reply falls below the community's threshold of quality. You may see it by logging in.