http://qs321.pair.com?node_id=689774


in reply to Open in for loop/array structure

As apl says, adding use strict and use warnings is always a good practice.

I am curious about this fragment:

print "$FN[$k]\n"; $filename = <$FN[$k]>; chomp ($filename); $file->open("< $filename") or die("Can't read the source:$!");
The expression <$FN[$k]> reads from the file handle $FN[$k]. Do your files out-02-00.txt, etc. contain a file name or do they contain data? If the latter, I think you want just $filename = $FN[$k];.

Update: The following curiosity has been cleared up by duff below.

The curious part is that my testing shows that $filename is actually being set to $FN[$k] (cygwin-perl 5.8.8). However, this supposedly equivalent code sets $filename to undef:

... $filename = readline($FN[$k]); ...
Update: Some more testing shows that if $f is the path of an existing file, then <$f> returns $f (assuming that $f has not been used as a file handle. Otherwise it returns undef. Ver interesting...

Replies are listed 'Best First'.
Re^2: Open in for loop/array structure
by duff (Parson) on Jun 02, 2008 at 23:45 UTC
    The expression <$FN$k> reads from the file handle $FN$k

    I don't think so. If the text inside <> isn't a simple scalar then the diamond operator turns into glob

      Oh that makes sense now - forgot about the glob operator.
        $filename = <$FN[$k]>; is still bad, though. Using glob without looping over its results makes no sense.
        use strict; use warnings; my @FN = qw( a b ); for my $k (0..$#FN) { my $filename = <$FN[$k]>; print("$filename\n"); }
        a Use of uninitialized value in concatenation (.) or string at 689777.pl + line 6.

        If @FN contains glob patterns, then he wants

        for (@FN) { while (defined(my $filename = glob($_))) { ... } }

        If @FN contains file names (as it seems to), then he wants

        for my $filename (@FN) { ... }

        Although it looks like @FN isn't needed at all.

        for (0..18, 20..28, 30..38) { my $filename = sprintf('out-02-%02d.txt', $_); ... }
Re^2: Open in for loop/array structure
by igotlongestname (Acolyte) on Jun 03, 2008 at 00:29 UTC
    Thank you all so much for your help, the simple removal of the <>'s fixed the problem. I'm new enough to not totally follow why filehandles caused the problem, yet the code worked on the first run through (the error version with filehandles included) and not on subsequent iterations, but I'm happy it works.

    Also, I added the "use strict" and got a trillion warnings, so removed it to verify completion which it did, I'll work on making it strict friendly too.

    Final question if someone has an understanding. This doesn't adjust my calculations at all, but is interesting for me in regards to better understanding. The first time through the for loop ($k=0), the 'print "$FN$k\n"' line prints the correct name (out-02-00.txt), but from then ($k>0) on I get an error that says "print() closed on filehandle OUT at isotopes-p7.perl line 14", which is the print line I just referred to. Is this because I "close(OUT)" at the bottom of the for loop and this is affecting the next iterations print statement until a new "OUT" file is opened? Any way to circumvent this? (I would just move the open(OUT) statement up, but I need $filename to correctly name it). Can I open a dummy out file for the time being or is there specific nomenclature for opening to terminal? I'll quit hazarding guesses and wait for an answer. Thanks again, any thoughts are welcome.

      yet the code worked on the first run through (the error version with filehandles included) and not on subsequent iterations, but I'm happy it works.

      You weren't using file handles. As already explained, you were using glob. And glob in scalar context acts as an iterator. The first time it's called, it returns the first match. The second time it's called, it returns the second match. And so on. When it's done, it returns undef. I've demonstrated that earlier in this thread.

      The first time you called <$FH[$k]> (when $k==0), it returns the first result for $k==0.
      The second time you called <$FH[$k]> (when $k==1), it returns the second result for $k==0 (undef).

      but from then ($k>0) on I get an error that says "print() closed on filehandle OUT at isotopes-p7.perl line 14"

      You told print to output to OUT (select (OUT);), but you closed OUT. Personally, I would remove the call to select and change
      print "$BU[$i-1] $MA1[$i-1] $MA2[$i-1]\n";
      to
      print OUT "$BU[$i-1] $MA1[$i-1] $MA2[$i-1]\n";
      I don't like using select. As you've encountered first hand, it introduces problems too easily.

        ikegami, Thanks for the very particular explanation, as that helps it make sense to me. I didn't understand what it meant by me using "glob", being that I'm quite limited in my understanding. Thanks for taking the time, it makes a lot more sense now. I had read what you wrote earlier, it just didn't all make sense since I'm Perl ignorant in a lot of things. Thanks again! ~Jack