Re: foreach - adding newlines?
by ikegami (Patriarch) on Feb 09, 2009 at 20:25 UTC
|
Ignoring your question for a second,
chomp;
should be
chomp($event_line); # in the loop
or
chomp(@EVENT_ARRAY); # outside the loop
Chomping $_ repeatedly are you are doing is useless since you never use $_.
Back to your question, the only ways to get the output you describe from the code you posted is if:
- if the value of $, contains a newline.
- if the value of $/ isn't a newline.
Would you care to add the following to the end of the code you posted and provide us the output?
{
use Data::Dumper;
print(Data::Dumper->new(
[
$,,
$",
$\,
$/,
\@EVENT_ARRAY,
\@array,
], [
'$,', qw(
$"
$\
$/
$EVENT_ARRAY
$array
)]
)->Useqq(1)->Dump());
}
Update: Fixed bad D::D syntax | [reply] [d/l] [select] |
|
|
Hrrm - coping the data dumper code results in an error:
Usage: PACKAGE->new(ARRAYREF, ARRAYREF) at ./22.pl line 70
| [reply] |
|
|
{
use Data::Dumper;
print(Data::Dumper->new(
[
$,,
$",
$\,
$/,
\@EVENT_ARRAY,
\@array,
], [qw(
$,
$"
$\
$/
$EVENT_ARRAY
$array
)]
)->Useqq(1)->Dump());
}
Update: (cf. johngg's reply) I suggested to move the parameters from Dump() to new() — otherwise I left ikegami's code as is. For reference, the original code was:
{
use Data::Dumper;
print(Data::Dumper->new()->Useqq(1)->Dump(
[
$,,
$",
$\,
$/,
\@EVENT_ARRAY,
\@array,
], [qw(
$,
$"
$\
$/
$EVENT_ARRAY
$array
)]
));
}
| [reply] [d/l] [select] |
|
|
|
|
| [reply] |
|
|
You're not ignoring the OP's question...the wrong thing is being chomp'd and that's the source of the problem :-)
| [reply] |
|
|
As I mentioned in the OP, I've tried chomp-ing various things in various places - is there somewhere specifically you would recommend? I'm open to try anything.
Tnx
| [reply] |
|
|
Improper chomping doesn't explain the presence of a new line between v1 and v2.
| [reply] |
|
|
|
|
|
Re: foreach - adding newlines?
by jwkrahn (Abbot) on Feb 09, 2009 at 20:19 UTC
|
You should run your program with the warnings and strict pragmas enabled to let perl help you find mistakes.
open (EVENTS_FILE, 't1Vevents.txt');
You should always verify that the file opened correctly:
open EVENTS_FILE, '<', 't1Vevents.txt' or die "Cannot open 't1Vevents.
+txt' $!";
@EVENT_ARRAY = <EVENTS_FILE>;
You could chomp your array elements here if you like:
chomp( my @EVENT_ARRAY = <EVENTS_FILE> );
But do you really need to read the whole file into memory?
foreach $event_line (@EVENT_ARRAY)
{
chomp;
foreach my $event_line ( @EVENT_ARRAY )
{
chomp $event_line;
if ($event_line =~ m/\s*d1/i)
The \s* at the beginning of the pattern is superfluous because it matches zero characters.
@array = (@array,$d1_value,$d2_value);
That is usually, and more efficiently, written as:
push @array, $d1_value, $d2_value;
So, in summary, you want code more like this:
use warnings;
use strict;
open EVENTS_FILE, '<', 't1Vevents.txt' or die "Cannot open 't1Vevents.
+txt' $!";
my ( @array, %values );
while ( <EVENTS_FILE> ) {
chomp;
if ( /([dD][12])/ ) {
$values{ lc $1 } = ( split /:/ )[ 1 ];
}
if ( /[dD]4/ ) {
push @array, @values{ 'd1', 'd2' };
}
}
close EVENTS_FILE;
print @array;
| [reply] [d/l] [select] |
Re: foreach - adding newlines?
by almut (Canon) on Feb 09, 2009 at 20:11 UTC
|
Just a little nitpick (nothing to do with your problem). In Perl,
@array = (@array,$d1_value,$d2_value);
would typically be written as
push @array, $d1_value, $d2_value;
| [reply] [d/l] [select] |
Re: foreach - adding newlines?
by GrandFather (Saint) on Feb 09, 2009 at 21:50 UTC
|
The keys issue is that chomp was chomping the default variable ($_). Most likely if you had used strictures (use strict; use warnings;) you'd have received warnings about chomping an undefined value. added: The other part of the sting is that your "push" adds two entries to the array where you really need one entry that is the concatenation of the two value strings.
However, there is some scope for a little tidying of your code. Consider:
use strict;
use warnings;
my $events = <<'END_EVENTS';
d1:v1
d2:v2
d4:v4
d1:v1
d2:v2
d4:v4
END_EVENTS
open my $eventsIn, '<', \$events or die "Failed to open event file: $!
+";
my $d2_value;
my $d1_value;
my @eventList;
while (<$eventsIn>) {
chomp;
my $title;
if (m/d1/i) {
($title, $d1_value) = split /:/;
} elsif (m/d2/i) {
($title, $d2_value) = split /:/;
} elsif (m/d4/i) {
push @eventList, "$d1_value$d2_value\n";
}
}
close $eventsIn;
print @eventList;
Prints:
v1v2
v1v2
Don't worry about the $event stuff - that's just to make a stand alone example without needing an external file.
Note the use of the three parameter open and the use of 'or die' to check the result and report errors. Use a lexical file handle ($eventsIn) rather than a bare word file handle (EVENTS_IN).
Use a while loop and handle things line by line. This code makes an end run around your chomp issue by actually using the default variable ($_) to store the line just read.
Declare variables in the smallest scope you can - $title is only used inside the loop so that is where it is declared. The other variables require a lifetime that is longer than one loop iteration so they are declared outside the loop.
To achieve the output you want you need to concatenate your two value strings and push the result. Your original code effectively pushed the two values into the array - you could do it that way, but printing becomes messy.
The current code is likely to fail in nasty ways if the input data is not exactly as you expect it to be. You should think hard about better validation techniques!
Perl's payment curve coincides with its learning curve.
| [reply] [d/l] [select] |
Re: foreach - adding newlines?
by MidLifeXis (Monsignor) on Feb 09, 2009 at 19:50 UTC
|
Could you perhaps give an example of your input? What type of machine is the data file generated on? What type of line endings are on the data file? What line endings are expected by the script ($/ variable)? Is binmode set?
Update: I missed the same thing as FunkyMonk. Unstruck my response.
| [reply] |
Re: foreach - adding newlines?
by hbm (Hermit) on Feb 09, 2009 at 20:03 UTC
|
Did you set $/ to undef or empty? If so, you might want to wrap it, plus the open, slurp, and close in {} to localize it. Otherwise, bare chomps that follow are affected.
And perhaps you want @EVENT_ARRAY = split/\n/,<EVENTS_FILE>;, to put each line into the array, rather than all the lines in one element?
| [reply] |
Re: foreach - adding newlines?
by FunkyMonk (Bishop) on Feb 09, 2009 at 19:48 UTC
|
| [reply] [d/l] [select] |
Re: foreach - adding newlines?
by nitehawk (Initiate) on Feb 09, 2009 at 20:31 UTC
|
The input file was created on a unix system, there doesn't seem to be any errant newlines introduced (everything is done locally on my workstation - there isn't any ftp-ing, and I've created most using plain 'ol vi)
$/ isn't set to anything explicitly - my understanding is that should default to \n, although I'll be more than willing to try it (although I can't seem to figure out how to do that offhand)
I tried adding the split on the @EVENT_ARRAY line, and the script outputs nothing, blank.
Thanks for the quick responses...
| [reply] |
|
|
On the command line, what output do you get when you do:
perl -lne 'print "Got CR" and last if /\r/' t1Vevents.txt
Do you see "Got CR" printed? | [reply] [d/l] [select] |
Re: foreach - adding newlines?
by nitehawk (Initiate) on Feb 11, 2009 at 19:31 UTC
|
I've finally managed to figure out what was going on.
Turns out that the file had CRs on _some_ of the lines. That was accounting for the weird behavior that chomp was working only some of the time.
Looking at my logs, I must have created the file on a windows machine at work when I was originally working with this. Since the original file was worked on by various scripts before getting to the one I was working with now, I lost track of where it was created.
This is why y'all are the monks, and I'm still re-learning :-)
Thanks so much for the help!! | [reply] |