[Israel.pm] Double Array

Offer Kaye offer.kaye at gmail.com
Tue Feb 8 23:55:53 PST 2005


On Wed, 09 Feb 2005 01:06:36 +0200, Georges EL OJAIMI wrote:
> Hello,
> 
> I tried the following:
> 
> $datafile = "data.txt";
> 
> open(FILE, "$datafile") || die "Unable to locate the path of the
> File.\n";
> while(defined($line=<FILE>)) {
>  my @lines = map { [ split(/;;;;/, $_) ] } split (/\n/, $line);
> }
> close (FILE);
> 
> my $len = scalar(@lines);
> print $len;
> 
> It is always giving me an empty array!!!
> 
> At the other hand if I try:
>         my @lines = map { [ split(/;;;;/, $_) ] } split (/\n/, <FILE>);
> It is returning the first line only!!!
> 
> BR
> Georges
> 

Hi Georges,
There are several things wrong with your code:
1. my @lines
You write this inside the scope of the "while" block, but than try to
access this variable outside this scope. "my" declares a variable to
be *lexicaly* scoped - this means *it cannot be seen* outside this
scope. Of course it will be empty!

2. split (/\n/, $line)
Your while loop already made sure you get a single line in $line. What
exactly are you trying to split here?

3.  my @lines = map { [ split(/;;;;/, $_) ] } split (/\n/, $line);
This line is inside a while loop, which iterates over the input lines.
So you are trying to re-populate @lines for each and every input line.
In other words, at every line, this code *overwrites*, instead of
*appending to*, the values in @lines. Even if you had not used "my",
you would have seen only the last line in your code.

4. split (/\n/, <FILE>)
Split expect a string (expression, to be more precise) as the second
argument. So by placing <FILE> here, you are placing the diamond
operator in scalar context. It has no choice but to return a single
line.

5. You're not using "use strict;" and "use warnings;" . This is
probably your biggest mistake.

Shlomo Yona gave you one possible solution that will work for you.
Here is another:
################ code ##############
use strict;
use warnings;
my $filename = "data.txt";
open(FILE, $filename) or die "Cannot open $filename for reading: $!\n";
my $filetext;
while(<FILE>) {
   $filetext .= $_;
}
close(FILE) or die "Cannot close $filename after reading: $!\n";
my @lines = map { [ split(/;;;;/, $_) ] } split (/\n/, $filetext);
################ end code ##############

Explanations of this code:
1. for every line of the input file, the while loop will assign that
line to $_ and the "$filetext .= $_;" code will append the line to the
scalar variable $filetext . After exiting the while loop, $filetext
will hold *the entire file contenct* in one large scalar variable.
Note that $filetext is defined *outside* the while loop, so it is
accessible from the entire file scope.

2. split (/\n/, $filetext)
The entire file contents, stored in the scalar $filetext, includes of
course embedded newlines ("\n" chars). So this split simply takes the
file contents and returns a list composed of the seperate lines of the
file.

3.  map { [ split(/;;;;/, $_) ] } 
map then takes the array returned by "split (/\n/, $filetext)", and
for each such line, returns an annonymous reference to an array
holding the result of splitting the current line using 4 ";" chars as
the delimiter.

Good luck, hope this helps :-)

-- 
Offer Kaye



More information about the Perl mailing list