I get an error such as "can't call method 'xxxx' on an undefined value" when attempting to check if an object has been created (by the perl module Bio::Perl).
Is there a general way of checking if an attribute has a value or not? I would have liked to do something like:
if ($the_object->the_attribute) {
But as long as the attribute is "undef", calling the method will only give me the error message. I have not been able to find a solution to this problem - which is real, because the object is created by the Bio::Perl module, and some attributes may or may not be set. Maybe I should add that I am not particularly perl-objects-savvy.
edit: Below is a relevant part of my code. The get_sequence() function is in the Bio::Perl module. On line 13, how can I make sure that there is a value (sequence in this case) before checking the length of it?
my @msgs;
my @sequence_objects;
my $maxlength = 0;
for ( @contigs ) {
my $seq_obj;
try {
$seq_obj = get_sequence( 'genbank', $_ );
}
catch Bio::Root::Exception with {
push @msgs, "Nothing found for $_ ";
};
if ( $seq_obj ) {
my $seq_length = length( $seq_obj->seq );
if ( $seq_length > $maxlength ) {
$maxlength = $seq_length;
}
push @sequence_objects, $seq_obj;
}
}
...
This checks if the return value of the method
the_attribute
is true. True means that it's not0
, the empty stringq{}
orundef
.But you said you want to know whether the object exists.
Let's go over some basics first.
It looks like you're confusing a few things.
First, your
$the_object
is supposed to be an object. It probably came from a call like this:Or maybe it was returned from some other function call. Maybe some other object returned it.
Now
the_attribute
is a method (that's like a function) that returns a specific piece of data in your object. Depending on the implementation of the class (the building plan of the object), if that attribute is not set (initialized), it might either just returnundef
, or some other value.But the error message you are seeing is not related to
the_attribute
. If it was, you'd just not call the code in the block. Theif
check would catch it, and decide to go toelse
, or do nothing if there is noelse
.Your error message says you are trying to call a method on something that is
undef
. We know you are calling thethe_attribute
accessor method on$the_object
. So$the_object
isundef
.The easiest way to check if something has a true value is to just put it in an
if
. But you already seem to know that.You've now checked that
$obj
is something that is true. So it could be an object. So you could now call your method.This will check the true-ness of
$obj
and only continue if there is something in$obj
. If not, it will never call the right hand side of the&&
and you will not get an error.But if you want to know whether
$obj
is an object that has a method, you can usecan
. Remember that attributes are just accessor methods to values stored inside the object.But that can blow up if
$obj
is not there.If you're not sure that
$obj
is really an object, you can use the Safe::Isa module. It provides a method$_call_if_object
1 that you can use to safely call your method on your maybe-object.Your call would translate to.
The same way you can use
$_isa
and$_can
from Safe::Isa.1) Yes, the method starts with a
$
, it's really a variable. If you want to learn more about how and why this works, watch the talk You did what? by mst.