如何检查对象的属性是否有值?

时间:2017-01-07 16:58:30

标签: perl bioperl

在尝试检查是否已创建对象时(由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;
    }
}

...

1 个答案:

答案 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_objectundef

检查某些内容是否具有真值的最简单方法是将其放入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?