views:

295

answers:

4

So I'm trying to read in a config. file in Perl. The config file uses a trailing backslash to indicate a line continuation. For instance, the file might look like this:

  === somefile ===
  foo=bar
  x=this\
  is\
  a\
  multiline statement.

I have code that reads in the file, and then processes the trailing backslash(es) to concatenate the lines. However, it looks like Perl already did it for me. For instance, the code:

  open(fh, 'somefile');
  @data = <fh>;
  print join('', @data);

prints:

  foo=bar
  x=thisisamultiline statement

Lo and behold, the '@data = ;' statement appears to have already handled the trailing backslash!

Is this defined behavior in Perl?

--Steve

+3  A: 

I don't know what exactly you are doing, but the code you gave us doesn't even run:

=> cat z.pl
#!/usr/bin/perl
fh = open('somefile', 'r');
@data = <fh>;
print join('', @data);

=> perl z.pl
Can't modify constant item in scalar assignment at z.pl line 2, near ");"
Execution of z.pl aborted due to compilation errors.

And if I change the snippet to be actual perl:

=> cat z.pl
#!/usr/bin/perl
open my $fh, '<', 'somefile';
my @data = <$fh>;
print join('', @data);

it clearly doesn't mangle the data:

=> perl z.pl
foo=bar
x=this\
is\
a\
multiline statement.
depesz
Oh yeah, sorry about the open statement. It reads: 'open(fh, 'somefile');'.Interesting, though, that it mangles the data for me, but not for you. I wonder if it's a Perl version thing. We're using 5.8.8; how about you?
Stephen Gross
I get the same -- I'm wondering if there's a module being required that the snippet above doesn't show.
Chris J
+5  A: 

I have no idea what you are seeing, but that is not valid Perl code and that is not a behavior in Perl. Here is some Perl code that does what you want:

#!/usr/bin/perl

use strict;
use warnings;

while (my $line = <DATA>) {
    #collapse lines that end with \
    while ($line =~ s/\\\n//) {
     $line .= <DATA>;
    }
    print $line;
}

__DATA__
foo=bar
x=this\
is\
a\
multiline statement.

Note: If you are typing the file in on the commandline like this:

perl -ple 1 <<!
foo\
bar
baz
!

Then you are seeing the effect of your shell, not Perl. Consider the following counterexample:

printf 'foo\\\nbar\nbaz\n' | perl -ple 1
Chas. Owens
+3  A: 

Perl does not do anything with your data unless you tell it to. You have done it wrong. Please post the exact code that you have.

Alan Haggai Alavi
I'm not kidding, folks. Perl processed the trailing newlines for me! Very weird behavior. I'm trying to figure out what the heck is going on...
Stephen Gross
As depesz and Chas have pointed out, the above code sample __WILL NOT__ execute at all since it is not valid Perl. So, it will be helpful if you can provide us with the exact code by removing the current code and pasting whatever code that causes the issue.
Alan Haggai Alavi
+4  A: 

My ConfigReader::Simple module supports continuation lines in config files, and should handle your config if it's the format in your question.

If you want to see how to do it yourself, check out the source for that module. It's not a lot of code.

brian d foy