Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Help with code

by speedo (Initiate)
on Jul 17, 2001 at 22:22 UTC ( #97400=perlquestion: print w/replies, xml ) Need Help??

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

Could someone please glance over this short program to figure out why the last foreach loop is not executing. I realize it's not proper ettiqutte to post the entire progrem but I cannot figure out where the prolem is stemming from, because it worked fine before adding the "strict" option and then declaring everything as local. It's my very first Perl program, so I'm guessing there's something blatantly obvious I've overlooked here.
#!/bin/perl -w use strict; use CGI qw(:standard); opendir IRESDIR, "/export/home/sylvia/ires"; my @iresdir = readdir IRESDIR; foreach my $dir (@iresdir) { push (my @dirlist, $dir); } closedir IRESDIR; foreach my $subdir (my @dirlist) { unless ( $subdir =~ /\.+/ ) { opendir SUBDIR, "/export/home/sylvia/ires/$subdir"; my @filelist = readdir SUBDIR; chdir "/export/home/sylvia/ires/$subdir"; foreach my $file (@filelist) { open IRESFILE, $file; while (<IRESFILE>) { if ( $_ =~ /^>gi\|(\d+).*/ ){ push (GILIST, $1); } } close IRESFILE; } closedir SUBDIR; } } ##### use Bio::Seq; use Bio::DB::GenBank; # creates a general "Sequence object called gb" my $gb = new Bio::DB::GenBank(); my %specieslist; my $q = new CGI; print $q->header, $q->start_html( -title => "IRES Elements in Species", -bgcolor =>" +#ffffcc" ), $q->h2( "IRES Elements Classified by Species" ), $q->hr; # creates a specific Sequence object called seq1 foreach my $entry (my @GILIST) { my $seq1 = $gb->get_Seq_by_acc("$entry") || die "$entry is not a r +eal accession number.\n"; my $speciesname = $seq1->species->common_name; unless ($speciesname eq $specieslist{$entry}) { $specieslist{$entry} = $speciesname; print p ("Gi# $entry is a $specieslist{$entry} nucleotide sequ +ence.\n"); } } print $q->end_html;
thank you monks! xxoxooox speedster

Replies are listed 'Best First'.
Re: Help with code
by myocom (Deacon) on Jul 17, 2001 at 22:31 UTC

    The problem is that you have blindly put in 'my' to keep strict happy. Unfortunately, you did so *everywhere*, including places where it isn't appropriate. The key bit that's causing your current problems is this:

    foreach my $subdir (my @dirlist) { #...

    The my @dirlist creates a new (and empty) @dirlist. You mean to refer to the one you tried to create earlier with this bit:

    my @iresdir = readdir IRESDIR; foreach my $dir (@iresdir) { push (my @dirlist, $dir); } closedir IRESDIR;

    ...however, that code also has an error. The code "push (my @dirlist, $dir);" pushes the current $dir onto a lexically scoped @dirlist. The problem is that the scope for @dirlist goes away once you hit that next closing brace on the next line. So effectively, you push the directory onto an array, then throw the array away.

    I suggest two things. One, read up on scoping. In particular, Dominus' Coping with Scoping article. Two, you're reinventing the wheel here. It would be best to use File::Find for this sort of thing.

      Thanks for suggesting the reference "Coping with Scoping". It was both informative and easy to read. Now that that problem is cleared up I can see that my program is crashing in the last foreach block. This is the error message I will get:
      MSG: unable to parse location successfully out of UO3722.1:1..548, ignoring feature (seqid=MMKCNAS2) ______________ Can't call method "location" on an undefined value at /usr/local/lib/perl5/site/5.6.1/Bio/SeqIO/ line 136.
      Now what does that mean? And is it the first or second problem that is causing the code to be aborted? Thanks again for your help, speedster.

        In general, messages like "Can't call method "location" on an undefined value ..." mean that you are trying to call a method on an object that doesn't exist (either you haven't created it with its constructor or the object has been destroyed). In this case, it appears that the code that is trying to call a method is in one of the Bio::SeqIO modules. That doesn't rule your code out entirely, but it does make it harder to track down the problem. You might check the docs for that series of modules to see if there are any hints there.

(ichimunki) Re: Help with code
by ichimunki (Priest) on Jul 17, 2001 at 22:34 UTC
    You are declaring @dirlist inside a loop, so it goes out of scope before it can be used in the next loop. Put a my @dirlist before the loop (and just push onto a not-my'ed @dirlist in the loop) and you should be fine.

    My question is, why are you creating a list from the readdir() and then copying the list to a second list? Why not just use @iresdir in your main for loop?

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://97400]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2022-06-29 06:53 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (95 votes). Check out past polls.