在尝试检查是否已创建对象时(由perl模块Bio :: Perl),我收到错误,例如“无法在未定义的值上调用方法'xxxx'。
是否有检查属性是否具有值的一般方法?我本来想做点什么:
if ($the_object->the_attribute) {
但只要该属性为“undef”,调用该方法只会给我错误信息。我无法找到这个问题的解决方案 - 这是真的,因为该对象是由Bio :: Perl模块创建的,并且某些属性可能设置也可能不设置。也许我应该补充一点,我并不是特别擅长对象。
编辑: 以下是我的代码的相关部分。 get_sequence()函数位于Bio :: Perl模块中。在第13行,如何在检查其长度之前确保存在值(在这种情况下为序列)?
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;
}
}
...
答案 0 :(得分:6)
if ($the_object->the_attribute) {
检查方法the_attribute
的返回值是否为真。 True 表示它不是0
,空字符串q{}
或undef
。
但是你说你想知道对象是否存在。
让我们先来看看一些基础知识。
# | this variable contains an object
# | this arrow -> tells Perl to call the method on the obj
# | | this is a method that is called on $the_object
# | | |
if ($the_object->the_attribute) {
# ( )
# the if checks the return value of the expression between those parenthesis
看起来你有点困惑。
首先,你的$the_object
应该是一个对象。它可能来自这样的电话:
my $the_object = Some::Class->new;
或许它是从其他一些函数调用返回的。也许还有一些其他对象返回了它。
my $the_object = $something_else->some_property_that_be_another_obj
现在the_attribute
是一种方法(就像一个函数),它返回对象中的特定数据。根据类的实现(对象的构建计划),如果未设置该属性( initialized ),它可能只返回undef
或其他值。< / p>
但您看到的错误消息与the_attribute
无关。如果是,您只是不调用块中的代码。 if
检查会抓住它,并决定转到else
,或者如果没有else
则不执行任何操作。
您的错误消息显示您正尝试在undef
的某个位置调用方法。我们知道您在the_attribute
上调用了$the_object
访问者方法。因此$the_object
是undef
。
检查某些内容是否具有真值的最简单方法是将其放入if
。但你似乎已经知道了。
if ($obj) {
# there is some non-false value in $obj
}
您现在已经检查$obj
是否属实。所以它可能是一个对象。所以你现在可以调用你的方法。
if ($obj && $obj->the_attribute) { ... }
这将检查$obj
的真实性,并且仅在$obj
中有内容时才会继续。如果没有,它将永远不会调用&&
的右侧,您将不会收到错误。
但是,如果您想知道$obj
是否是具有方法的对象,则可以使用can
。请记住,属性只是存储在对象中的值的访问器方法。
if ($obj->can('the_attribute')) {
# $obj has a method the_attribute
}
但如果$obj
不存在,那可能会爆发。
如果您不确定$obj
是否真的是对象,则可以使用Safe::Isa模块。它提供了一个方法$_call_if_object
1 ,您可以使用该方法在您的Maybe-object上安全地调用您的方法。
$maybe_an_object->$_call_if_object(method_name => @args);
您的电话会转换为。
my $the_attribute = $obj->$_call_if_object('the_attribute');
if ($the_attribute) {
# there is a value in the_attribute
}
您可以使用Safe :: Isa中的$_isa
和$_can
。
1)是的,该方法以$
开头,它实际上是一个变量。如果您想了解有关其工作原理和原因的更多信息,请观看mst的演讲You did what?。