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

How to check whether an attribute of an object has a value?

我在尝试检查对象是否已创建(由 perl 模块 Bio::Perl)时收到诸如 "can't call method 'xxxx' on an undefined value" 之类的错误。

是否有通用的方法来检查属性是否具有值?我本来想做这样的事情:

if ($the_object->the_attribute) {

但是只要属性是"undef",调用方法只会给我报错信息。我一直没能找到这个问题的解决方案 - 这是真实的,因为对象是由 Bio::Perl 模块创建的,并且可能设置也可能不设置某些属性。也许我应该补充一点,我不是特别精通 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;
    }
}

...
if ($the_object->the_attribute) {

这将检查方法 the_attribute 的 return 值是否为真。 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;

或者它可能是 return 从其他函数调用中编辑的。也许其他对象 return 编辑了它。

my $the_object = $something_else->some_property_that_be_another_obj

现在 the_attribute 是一种方法(类似于函数),它 return 是您对象中的特定数据片段。根据 class(对象的构建计划)的实现,如果未设置该属性(已初始化),它可能只是 return undef,或其他一些值。

但是您看到的错误消息与 the_attribute 无关。如果是,您就不会调用块中的代码。 if 检查会捕获它,并决定去 else,或者如果没有 else.

则什么都不做

您的错误消息说您正在尝试调用 undef 上的方法。我们知道您正在 $the_object 上调用 the_attribute 访问器方法。所以 $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_object1,您可以使用该方法在您的可能对象上安全地调用您的方法。

$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?