views:

354

answers:

4
#!usr/bin/perl
@array = ();
open(myfile,"sometext.txt");
while(<myfile>)
{
    chomp;
    push(@array,[split(" ")]);
}
close(myfile);
print @array[0];

Instead of printing the elements of the first array in this multidimensional array, it outputs the hexadecimal(?) pointer reference. If anyone knows how I can print this array, please post how and it will be greatly appreciated.

+3  A: 

Perl doesn't do exactly what you want in this case. You need to explicitly tell Perl how to print out your array.

Try this:

use Data::Dumper;
print Dumper( $array[0] );

Or this:

foreach my $element ( @{ $array[0] } ) {
    print $element, "\n";
}

Or this:

print join ' ', @{ $array[0] };
print "\n";

Here's your example code, re-written a bit to do more error checking, and turn on strict and warnings. When these are turned on, Perl will do more checking and restrict you to a safer subset of the language.

#!/usr/bin/perl

use strict;
use warnings; 

my @arrays;
my $fn = 'summary.txt';
open FILE, "<$fn" or die "Error opening file ($!)";

while( my $line = <FILE> ) {
    chomp $line;
    my @data = split ' ', $line;
    push @arrays, \@data;
}
close FILE or die $!;

# print out comma-separated arrays, one per line
foreach my $array (@arrays) {
    print join ",", @$array;
    print "\n";
}
James Thompson
@James Thompson `split /\s+/` and `split ' '` are different.
Sinan Ünür
+2  A: 

Here you go.

Perl's multi-dimensional arrays are really arrays of references to the arrays. In perl a reference is just a scalar variable. So, when you are trying to print your whole array it prints out just that reference. You need to use the @{} to change the context of the scalar to array.

#!/usr/bin/perl
@array = ();
open(myfile,"sometext.txt");
while(<myfile>)
{
    chomp;
    push(@array,[split(" ")]);
}
close(myfile);
print @{@array[0]};
Vlad
@Vlad: Not really *arrays of arrays* but arrays of **references to arrays**. Plus, you shebang line is very likely wrong.
Sinan Ünür
The shebang line was written like that in the original post.
James Thompson
still, its wrong. full Paths in *nix start with "/", therefore the shebang is `#!/usr/bin/perl`
ghostdog74
Shebang line was wrong. I just cut and pasted the original code didn't pay attention to the first line.
Vlad
That `@{@array[0]}` might work, but it smells bad.
mobrule
What's wrong with @{array[0]} line. Perfectly valid way to force the context.
Vlad
+10  A: 

You should use strict and warnings. The latter would have told you the way to access the first row is $array[0]. Now, that value is a reference to the anonymous array you pushed on to @array. So, you need to dereference that: print "@{ $array[0] }\n";

#!/usr/bin/perl

use strict; use warnings;

my @array;

my $input_file = 'sometext.txt';

open my $input, '<', $input_file
    or die "Cannot open '$input_file': $!";

while(<$input>) {
    chomp;
    push @array, [ split ];
}

close $input;

print "@$_\n" for @array;
Sinan Ünür
+1  A: 

I'm surprised that nobody mentioned this yet, but the standard way to print complex data is Data::Dumper.

use Data::Dumper;
#...
print Dumper( $array[0] );

You could also do:

print Dumper( @array );

Of course, you can't beat the ease of Smart::Comments, all you have to do is create comment using three initial hashes:

use Smart::Comments;
#...
### @array
Axeman