Angharad has asked for the wisdom of the Perl Monks concerning the following question:

Hi people I'm almoat embarassed at this one but anyway .. I have a text file like so ...
-0.821,-0.247,0.001,-0.77 -1.045,-0.289,0.035,-0.962 -1.345,-0.345,0.048,-1.188 -1.674,-0.421,0.041,-1.428
And all I actually want to do is to extract the values and push them into a PDL matrix ... Code so far ... (well the relevant bit anyway ..)
#!/usr/bin/perl use PDL; use PDL::Matrix; $file = $ARGV[0]; open(DATA, "$file") || die "Error: Unable to open $file:$!\n"; my $d = [[],[], [], []]; while ( <DATA> ) { chomp; my @1 = split(/,/); push @{$d->[0]}, $l[0]; push @{$d->[1]}, $l[1]; push @{$d->[2]}, $l[2]; push @{$d->[3]}, $l[3]; } $d = PDL::Matrix->pdl($d);
In a nutshell, it doesnt work. I get the following error.
Can't use global @1 in "my" at ./DSSP2CD_new.pl line (value here), nea +r "my @1 "
Any help/suggestions much appreciated.

Replies are listed 'Best First'.
Re: problem with split command
by holli (Abbot) on Sep 05, 2005 at 10:11 UTC
    Rename your "@1" to something else, eg. "@line". Then it works.


    holli, /regexed monk/
Re: problem with split command
by davis (Vicar) on Sep 05, 2005 at 10:13 UTC
    The problem is you're actually declaring your array variable as "@1" (that's a "one"). Variable names can't start with a numeral. Here's your script, cleaned up a bit (remember to use warnings and stricture, use "or" where you can instead of "||", and you might want to try lexical (scalar) filehandles). This version actually compiles, but I don't know what you want it to do
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; use PDL; use PDL::Matrix; my $file = $ARGV[0]; #open(DATA, "<", $file) #or die "Error: Unable to open $file:$!\n"; my $d = [[],[], [], []]; while ( <DATA> ) { chomp; my @l = split(/,/); push @{$d->[0]}, $l[0]; push @{$d->[1]}, $l[1]; push @{$d->[2]}, $l[2]; push @{$d->[3]}, $l[3]; } $d = PDL::Matrix->pdl($d); __DATA__ -0.821,-0.247,0.001,-0.77 -1.045,-0.289,0.035,-0.962 -1.345,-0.345,0.048,-1.188 -1.674,-0.421,0.041,-1.428

    davis
    Kids, you tried your hardest, and you failed miserably. The lesson is: Never try.
Re: problem with split command
by calin (Deacon) on Sep 05, 2005 at 10:39 UTC
    my $d = [[],[], [], []];

    You don't need to pre-initialise your deep data structures. They'll pop up automagically when you first use them. It's called autovivification. So a

    my $d;

    should suffice.

    Update: To avoid repetitive pushes you could define this function:

    sub pushsome { my $AoAref = shift; for (my $i = 0 ; $i <= $#_ ; $i++) { push @{$AoAref->[$i]}, $_[$i]; } }

    and then

    while ( <DATA> ) { chomp; pushsome $d, split /,/; }

    However in this case you need to pre-define $d as an array reference (my $d = [];) ; first-level autovivification can't work through subroutine calls.

    Better off IMO is to get rid of the "reference to an array of arrays" ($r) and use an up-front @AoA. Here's your revamped code:

    #!/usr/bin/perl use strict; use warnings; use PDL; use PDL::Matrix; sub pushsome { my $AoAref = shift; for (my $i = 0 ; $i <= $#_ ; $i++) { push @{$AoAref->[$i]}, $_[$i]; } } sub fetchdata { my $file = shift; my @AoA; open(DATA, $file) || die "Error: Unable to open $file:$!\n"; while (<DATA>) { chomp; pushsome \@AoA, split /,/; } close DATA; PDL::Matrix->pdl(\@AoA); } # main program @ARGV or die "Please supply a data file on the command line!\n"; my $d = fetchdata( shift ); # ...
      Hey, thanks a lot. Much appreciated.
Re: problem with split command
by Angharad (Pilgrim) on Sep 05, 2005 at 10:26 UTC
    silly me ... thanks a lot for your help.