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

Hello,
My method produces an error message stating that it can't call a "next_hit" method on an undefined value.

sub hu_bl2seq_parser{ my ($maid, $maid_dir) = @_; # Get the report my $in = new Bio::SearchIO(-format => 'blast', -file => ">".$maid_dir."\\".$maid."aln_hu +.aln", -report_type => 'blastn'); #open(my $out, ">$maid_dir/".$maid."aln_hu_parsed.out"); + #my $out = Bio::AlignIO->newFh(-format => 'clustalw' ); my $result=$in->next_result; my($hu_aln,$hu_mismatches); # Get info about the first hit my $hit = $result->next_hit; my $name = $hit->name; # get info about the first hsp of the first hit my $hsp = $hit->next_hsp; # get the alignment object my $aln = $hsp->get_aln; #my $percent_id = $hsp->percent_identity; #my $aln_length = $hsp->length('total'); my @mismatches = $hsp->seq_inds('query','nomatch'); my $aln_str=""; # access the alignment string my $strIO=IO::String->new($aln_str); # write the string alignio in clustalw format my $alnio = Bio::AlignIO->new(-format => 'clustalw', -fh=>$strIO); # now the actual alignment string is accessable for printing or in + this case moving to a db table $alnio->write_aln($aln); $hu_aln=$aln_str; $hu_mismatches = scalar @mismatches; return($hu_aln, $hu_mismatches); }
The problem is at "my $hit = $result->next_hit;"
Any help will be appreciated.
LomSpace

Replies are listed 'Best First'.
Re: I don't understand error message
by ikegami (Patriarch) on Jun 16, 2009 at 15:31 UTC
    $result's value is undef, because ->next_result() returned undef, probably because there isn't a next result.
Re: I don't understand error message
by SuicideJunkie (Vicar) on Jun 16, 2009 at 15:33 UTC
    Sounds fairly straightforward.
    Can't call next_hit on an undefined value, so therefore $result is currently undefined.

    You set $result just above that line using:
    my $result=$in->next_result;

    So, the logical reason would be that next_result is returning undef. Perhaps because there are no further results to return.
    You should check return values for error values before using them.
      There is only one result. So, I am not clear on how to define it? Any suggestions?
        You say there is one result, but the evidence (an undef being returned) indicates that there is not.
        If my $result=$in->next_result; is putting undef into $result there must be a reason for it. The key is figuring out what that could be.

        Since $in is a new Bio::SearchIO(...), you should look at that documentation to find the conditions under which next_result will be undef.

        I could guess and suggest that perhaps your file is empty, does not exist, does not have permission for you to view it, or even contains data in the wrong format.

        PS:
        Out of curiosity, why are you prepending ">" to the filename you are passing in? It seems unlikely that that would result in a valid file name.
Re: I don't understand error message
by CountZero (Bishop) on Jun 16, 2009 at 17:58 UTC
    You should read the manual of Bio::SearchIO. It says:
    Reads the next ResultI object from the stream and returns it. Certain driver modules may encounter entries in the stream that are either misformatted or that use syntax not yet understood by the driver. If such an incident is recoverable, e.g., by dismissing a feature of a feature table or some other non-mandatory part of an entry, the driver will issue a warning. In the case of a non-recoverable situation an exception will be thrown.
    If this function returns undef, it is likely (although the manual is silent about it) to indicate an "End-Of-File" or "End-of-Stream" situation rather than an error as errors will throw an exception.

    It is a common idiom to wrap methods such as object->next_SOMETHING in a while-loop to automatically run through all results and finish when there are no more "next" things to process.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I have read the manual, and this is not so clear to me. So, my problem may be solved with while loops? I'll attempt that.

      Thanks!
        So, my problem may be solved with while loops?
        If you are interested in looping through all "next" results, that would be a good start.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: I don't understand error message
by moritz (Cardinal) on Jun 16, 2009 at 15:33 UTC
    It means that $result is undef, ie $in->next_result didn't return any value.

      A sub in scalar context (as is the case here) cannot do anything but return a value. (It crashes Perl when they don't.)

      - People for the equitable treatment of undef

Re: I don't understand error message
by llancet (Friar) on Jun 17, 2009 at 01:04 UTC
    It seems SearchIO failed to parse your file.

    Furthermore, I've found several questions, in:
    my $in = new Bio::SearchIO(-format => 'blast', -file => ">".$maid_dir."\\".$maid."aln_hu +.aln", -report_type => 'blastn');


    1: Are you sure you are reading a BLAST file, while your file extension is "aln", which seems to be a multiple sequence alignment?

    2: Are you sure you need "-report_type"? In the documentation, it says only if you're reading a blast2seq result, you need to use that