http://www.perlmonks.org?node_id=1057123


in reply to Iterator to parse multiline string with \\n terminator

No need for recursion. Just change the anonymous sub as follows (untested):

my $fh_iterator = sub { my $fh = shift; my $line = $fh->getline(); $line .= $fh->getline() while $line =~ m{\\$}; return $line; }

Update: Here is a tested script which eliminates the Use of uninitialized value warning reported in the post below:

use strict; use warnings; use IO::File; my $filename = shift @ARGV; my $fh = IO::File->new($filename, 'r'); sub fh_iterator { my $fh = shift; my $line = $fh->getline(); if (defined $line) { $line .= $fh->getline() while $line =~ m{\\$}; } return $line; } while (my $line = fh_iterator($fh)) { print $line; }

Output:

16:29 >perl 738_SoPW.pl test.file foo \ bar \ baz single line 16:29 >

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^2: Iterator to parse multiline string with \\n terminator
by three18ti (Monk) on Oct 06, 2013 at 06:08 UTC
    EDIT: Oh, I'm an idiot... for got to change:
    $line .= $fh_iterator while $line =~ m{\\$};

    To:

    $line .= $fh->getline while $line =~ m{\\$};

    However, the code does return the error below on the last line of my test file...

    Use of uninitialized value $line in pattern match (m//) at parser3.pl +line 17, <GEN0> line 5.

    Begin Original Post

    Hmm... well, I get a new error at least:/p>

    Use of uninitialized value $line in pattern match (m//) at parser3.pl +line 17, <GEN0> line 5.

    Here's the accompanying code and test file:

    #/usr/bin/perl use strict; use warnings; use IO::File; use 5.010; my $filename = shift @ARGV; my $fh = IO::File->new($filename, 'r'); sub fh_iterator { my $fh = shift; my $line = $fh->getline; $line .= fh_iterator($fh) while $line =~ m{\\$}; } while (my $line = fh_iterator $fh ) { print $line; } __END___ test.file foo \ bar \ baz single line
Re^2: Iterator to parse multiline string with \\n terminator
by three18ti (Monk) on Oct 06, 2013 at 09:20 UTC

    WRT your edit

    What do you think about a return instead of an if? e.g.:

    sub fh_iterator { my $fh = shift; my $line = $fh->getline(); return $line unless $line; $line .= $fh->getline() while $line =~ m{\\$}; return $line; }

    I don't think there's any functional difference, but one may be more readable than the other...

    Thanks for your help!

      return $line unless $line;
      make that:
      return $line unless defined $line;
      theoretically the last line could be missing the newline and only contain "0". then $line would be false and ignored with your code.

      ++tinita for highlighting the important difference between testing for definedness and testing for truth (see perlsyn#Truth-and-Falsehood).

      But even with the correction I prefer my version. Readability is in the eye of the programmer, but the first high-level programming subject I took at Uni (in Pascal!) emphasised structured programming, and this has remained with me. I prefer a function to have a single exit point (at the end) where possible. In Perl this is not always optimum, so I’ve had to learn to be flexible. But when — as in this case — the structured version is as straightforward as the non-structured one, I prefer the former. YMMV.

      As always in Perl, TMTOWTDI.

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,