in reply to Changing name of ARRAY in each iteration

Hi cool,

First of all, please put the following two lines at the top of your program:

use strict; use warnings;

Then, when you rerun the program, you will get a bunch of errors:

Global symbol "$dinu_r" requires explicit package name at x line 15. Global symbol "@energy" requires explicit package name at x line 20. Global symbol "@energy" requires explicit package name at x line 21. Type of arg 1 to push must be array (not concatenation (.) or string) +at x line 21, near "})" syntax error at x line 29, near "..." Execution of x aborted due to compilation errors.

Obviously the syntax error at x line 29, near "..." is caused by the "..." you used to show omitted code, so you can ignore that (or, better yet, comment it out).  For the 3 errors containing "requires explicit package name", you should declare them somewhere using "my", and assign them as well.  Until you do, we can't know for sure what the problem in your program is.

Another thing you should absolutely do is provide error-checking when opening files doesn't work.  If you aren't successful opening an input file, it's pretty pointless to keep going, and trying to read from the input filehandle!  Here's an example of how you can check the results of your open:

my $input = "shuffle$x"; open (AA, $input) or die "Can't open input '$input' ($!)\n"; # LINE A

If you can fix these problems, try resubmitting the program.


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: Changing name of ARRAY in each iteration
by cool (Scribe) on Aug 10, 2006 at 14:33 UTC

    Dear Liverpole,
    First of all thanx for taking interest in this. Following is the code the way you asked. Now it is showing these errors
    lobal symbol "@energy" requires explicit package name at monk.pl line 29. Type of arg 1 to push must be array (not concatenation (.) or string) at monk.pl line 29, near "})" Execution of monk.pl aborted due to compilation errors.
    By the way, to rephrase my question, as 'second reply' has rightly put it, I am looking to change the array name dynamically... How this can be possible? Pl help..
    #!/usr/bin/perl -w use strict; my $dinu_r; my $energy; my @energy1; my @energy2; my @energy3; my @energy4; my @energy5; my $i; for (my $x=1; $x<=5; $x++) { open (AA, "shuffle$x")or die "Can't open input ($!)\n"; # LINE A my $Sequence; $i=length($Sequence); while (<AA>) { $Sequence=$_; } close(AA); my %Winenergy = Energy($Sequence,$dinu_r); open (OUT, ">shuffle$x.stb"); # LINE B foreach my $el1(sort{$a <=> $b} keys %Winenergy) { push(@energy.$x , $Winenergy{$el1}); #LINE C # print OUT "$el1\t $Winenergy{$el1}\n"; } #print OUT "\n"; close (OUT); } sub Energy{ my ($sequence,$dinu_r) = @_; my %dinu = %$dinu_r; my $frame=1; my $win=15; my $lensequence = length($sequence); #length of the genome sequence my $limit1 = $lensequence-$win+1; #no of windows my $wincenpos = 1+($win-1)/2; #centre postion for the first window my %winenergy = (); my $j = 0; #starting position of the window while($j<$limit1) { my $winseq = substr($sequence,$j,$win); my $energy = 0; for(my $k =0; $k < $win-1; $k++) { my $dinucle_temp = substr($winseq,$k,2); my $dinucle = uc($dinucle_temp); $energy = $energy + $dinu{$dinucle}; }#end for $k my $wincentre = $j+$wincenpos; $winenergy{$wincentre} = $energy; $j = $j+$frame; }#end for $j return %winenergy; } open(FILE,">total_shuffle.stb"); my $m=8; for(my $j=0;$j<$i;$j++) { my $avg = ($energy1[$j]+$energy2[$j]+$energy3[$j]+$energy4[$j]+$energy +5[$j])/5; print FILE "$m\t$avg\n"; $m++; } close (FILE);
      I am looking to change the array name dynamically... How this can be possible?

      It's possible using a Perl feature called "symbolic references", but they are usually a very dangerous idea. So dangerous, in fact, that one of the effects of adding "use strict" to your program (and you should _always_ add "use strict" to your program) is to ban their use.

      I know you think that this is the best solution to your problem, but it really isn't. There's always a better solution.

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

      Looking at this "more complete"(?) version of your code, it's actually easier for me to say how it can be done without trying to use "dynamic array names", and instead using an appropriate data structure (an array of arrays, or AoA). So I'll try to do that by showing how I would rewrite this.

      But in trying to revise your code, I found a number of other problems, which will probably lead to unintended results. So, in addition to recasting the code to use an AoA, I made other changes to improve legibility: moved things around a bit, applied proper indentation (which does matter), used the simpler form of loop control, removed some unnecessary code, and removed your original comments.

      Now, the only comments are the ones I put in, mostly (the "um..." ones) to mark things that make no sense or problems that need to be solved (but I don't know how you should solve them, because I don't know enough about your data or your real goals). This version compiles with no errors or warnings, but when you run it, there will certainly be a run-time error.

      #!/usr/bin/perl -w use strict; my $dinu_r; # um... nothing is ever assigned to this variable my @energyGrid; # this will be the AoA my $i; for my $x ( 1 .. 5 ) { open( AA, "shuffle$x" ) or die "Can't open shuffle$x ($!)\n"; # LI +NE A my $Sequence; $i=length($Sequence); # um... this is always zero while (<AA>) { $Sequence=$_; # um... $Sequence will only be the last line of + "shuffle$x" } close(AA); my %Winenergy = Energy( $Sequence, $dinu_r ); open (OUT, ">shuffle$x.stb"); # LINE B foreach my $el1 (sort{$a <=> $b} keys %Winenergy) { push( @{$energyGrid[$x]} , $Winenergy{$el1} ); #LINE C } close (OUT); } open(FILE,">total_shuffle.stb"); my $m=8; for my $j ( 0 .. $i ) # um... $i is still zero here { my $avg = 0; for my $x ( 1 .. 5 ) { $avg += $energyGrid[$x][$j]; } $avg /= 5; print FILE "$m\t$avg\n"; $m++; } close (FILE); sub Energy { my ($sequence,$dinu_r) = @_; my %dinu = %$dinu_r; # um... $dinu_r was never a hash ref # (and is undef), so this line will cause a run-time error my $win=15; my $limit1 = length( $sequence ) - $win + 1; my $wincenpos = 1 + ($win-1)/2; my %winenergy = (); for my $j ( 0 .. $limit1-1 ) { my $winseq = substr($sequence,$j,$win); my $energy = 0; for my $k ( 0 .. $win-2 ) { my $dinucle_temp = substr($winseq,$k,2); my $dinucle = uc($dinucle_temp); $energy = $energy + $dinu{$dinucle}; } my $wincentre = $j+$wincenpos; $winenergy{$wincentre} = $energy; } return %winenergy; }
        Hi graff!
        Thanks for the effort you have put man. The things you have mentioned here, can not be taught by any book. I desperatly want to improve my Perl skills but that process is really slow as no experiance coder (monk :) ) is around.

        I sincerely thank you and other monks who had taken time for my problem. One more thing, if I will be getting this kind of support, it wont be long that I will be helping some one out

        Keep rocking monks!!