Reputation: 432
I´m doing some analysis of my data with Perl, using a specific package of BioPerl.
I read some recommendations about this problem in another post, but I really don´t understand how this applies to my script.
This is my script:
use strict;
use warnings;
use Bio::AlignIO;
use Bio::Align::DNAStatistics;
my $file = $ARGV[0];
my $idfile = $ARGV[1];
if ($file eq "" ) {
$file = "NT_MSA_S_protein.fasta";
} elsif ($idfile eq "" ) {
$idfile = "NT_ID_S_protein.csv";
}
my @contentIDS;
open (LIST, $idfile) or die;
while (my $l = <LIST>) {
$l =~ s/\n//g; # delete newline
$l =~ s/\r//g; # delete CR
next if (length($l) < 1);
push @contentIDS, $l;
}
close LIST;
my $stats = Bio::Align::DNAStatistics->new();
my $alignin = Bio::AlignIO->new(-format => 'fasta', -file => $file); # MSA file
while (my $aln = $alignin->next_aln) {
my $matrix = $stats->distance(-align => $aln, -method => 'Tajima-Nei');
WL1:
foreach my $aaa (@contentIDS) { ### ID #1
WL2:
foreach my $baa (@contentIDS) { ### ID #2
next (WL2) if ($aaa eq $baa);
my $data = $matrix->get_entry($aaa, $baa);
print "DISTANCE\t$aaa\t$baa\t$data\n";
} # END WL2
} # END WL1
}
This is the message error:
Can't locate object method "get_entry" via package "0" (perhaps you forgot to load "0"?) at Tajima-Nei_Distance_NV.pl lin$
I think that the problem is related to "=> instead ->", maybe. I just suppose.
Upvotes: 2
Views: 1339
Reputation: 66883
The message you got, Can't locate object method... (from perldiag), means
(F) You called a method on a class that did not exist, and the method could not be found in UNIVERSAL. This often means that a method requires a package that has not been loaded.
So something isn't right with the object on which the call is made.† Either such class doesn't exist, as the docs quoted above say, or the object on which the method is called isn't good (something failed earlier) ... let's trace that call through code and docs.
The chain starts at the Bio::Align::DNAStatistics::distance method, which returns an object of the class Bio::Matrix::PhylipDist. The syntax is correct so we expect a good matrix object (or hope for an outright error if details are wrong).
However, the part of the error message that says
... via package "0" ...
clearly means that something is in fact wrong with the matrix object (it's 0
-- not an object at all), and so with the call that was supposed to return that object,
my $matrix = $stats->distance(-align => $aln, -method => 'Tajima-Nei');
Judging by one of the distance methods listed further down in docs, D_TajimaNei, you may need to say -method => 'TajimaNei'
(no hyphen). One might wish that the method croak
s on an error like this, as I don't see a point in returning a 0
, but since this isn't the case it may be a good idea to add extra checks when using this class.
Also note that the method get_entry can only be called without arguments, get_entry()
, and that the attempted get_entry($aaa, $baa)
method (which would take two arguments) doesn't exist.‡ That would draw the other, related, error mentioned in the footnote †.
† Note that the parenthetical remark in this method's entry in perldiag
is what specifies that the error is with the object itself, while the previous entry in perldiag
, with the exact same syntax except for that parenthetical remark, is raised when something is wrong with how the method is called. I recommend to always check all parts of the offending statement.
‡ According to the documentation current at the time of this posting
Upvotes: 6
Reputation: 164699
It's telling you that the value of $matrix is 0. Perl is interpreting 0 as a class name. Something is wrong with your assignment to $matrix.
my $matrix = $stats->distance(-align => $aln, -method => 'Tajima-Nei');
I think you want -method => 'TajimaNei'
. Check $stats->available_distance_methods.
Normally you can't have a class named 0, but with enough thrust pigs fly just fine.
*{"0::hello"} = sub { "Hello\n" };
package main;
my $matrix = 0;
print $matrix->hello;
Upvotes: 6