in reply to Re^2: writing two files (different in length) to one output
in thread writing two files (different in length) to one output

You are absolutely right! My fault ...:)

> "eof" is also nice because you get that status right after reading the last valid line.

Yep, not sure how efficient the implementation is, but rotating over iterators is usually not that much fun...

I recently stumbled over eof while reading perlfunc for the "Overview scalar vs list context?" thread.

FWIW, my approach would be something like:

open ONE, '<' ,'one.txt'; open TWO, '<' ,'two.txt'; my $finished_1, $finished_2; until ( $finished_1 and $finished_2) { my $line1 = <ONE>; my $line2 = <TWO>; chomp $line1, $line2; print "$line1 \t $line2"; ++$finished_1, seek ONE,0,0 if eof ONE; ++$finished_2, seek TWO,0,0 if eof TWO; }
out (ONE shortened to 2 lines)
1 1 2 2 1 3 2 4 1 5

Cheers Rolf
(addicted to the Perl Programming Language and ☆☆☆☆ :)
Je suis Charlie!

Replies are listed 'Best First'.
Re^4: writing two files (different in length) to one output
by Marshall (Canon) on May 30, 2017 at 18:54 UTC
    Hi Rolf!
    Your code works, but I would make 2 modifications.
    my $finished_1, $finished_2; # should be: my ($finished_1, $finished_2); # list context is needed for the "my" to apply to # both variables. chomp $line1, $line2; # the chomp() does not operate on $line2. # Again, list context is needed... # chomp ($line1, $line2); # but that requires a change in the print # # e.g., print "$line1 \t $line2\n"; # # Of course code could be just: # chomp $line1; #leave $line2 out of it! # My coding preference would be to be symmetrical, # i.e. # chomp ($line1, $line2); # and add the extra $line2 line ending back in # during the print. # # instead of: print "$line1 \t $line2"; # print "$line1 \t $line2\n";
    Yes eof test is much better!
    My first impulse, at first glance was to write a read_circular subroutine. But this winds up being "messy":
    sub read_circular { my $fh = shift; my $line; do { $line = <$fh>; seek ($fh,0,0) if !(defined $line); #restart from beginning }until (defined $line); return $line; }
    Or some such formulation...
    If we have to wait until the read() is undefined, then a "re-read" is necessary. The "eof" status happens right after the last valid line is read. So no "re-reading" is needed. A far superior solution++.

    ...not sure how efficient the implementation is...
    I am quite sure that your code will run very well. I will point out again, that
    ++$finished_1, seek ONE,0,0 if eof ONE; # this is the same as if ( eof ONE) { $finished_1++; #post or pre-increment the same seek ONE,0,0; } # the number of source code lines does not equate # directly into actual "code savings". The more # wordy "if" loop will code into very similar, if # not the exactly the same executing code
    Again, Nice Idea using eof test++.
      > Again, list context is needed..

      of course you are right, that's the punishment for not using strictures. :)

      Just one nitpick: the benefit of parens here is technically not "list context" but precedence.

      my has a higher precedence than comma, to allow other constructs like (my $a,my $b) =...

      Maybe the perldoc should be clearer writing my (VARLIST) like in the doc of chomp (LIST)

      > the number of source code lines does not equate directly into actual "code savings

      Of course not, my intention here was readability.

      It's right away obvious that both files are treated symmetrically, if the code is aligned in 2 dimensions.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Je suis Charlie!

        The use of "precedence" instead of "list context" is better. Thanks for the clarification!

        As to whether or not the comma operator is more readable in this situation, I leave that to the reader(s) to decide. My C background enables me to easily understand this construct, but many folks here may not find that "readable".

        I think we are "drilling way down into the dirt here". The main point that is important here is testing of eof instead of !defined. I personally declare this thread a "success". Been "beat to death" and a definite, informative, high-performance, clear answer has been arrived at.