2017-01-07 97 views
1

當嘗試檢查一個對象是否已被創建(由perl模塊Bio :: Perl)時,我得到一個錯誤,例如「對一個未定義的值調用方法'xxxx'」。如何檢查對象的屬性是否有值?

是否有一種檢查屬性是否有值的通用方法?我會喜歡做這樣的事情:

if ($the_object->the_attribute) { 

但只要該屬性是「undef」,調用該方法只會給我錯誤消息。我一直無法找到這個問題的解決方案 - 這是真實的,因爲該對象是由Bio :: Perl模塊創建的,並且可能會或可能不會設置一些屬性。也許我應該補充一點,我並不特別精通perl-objects。

編輯: 下面是我的代碼的相關部分。 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

不,你不檢查obj是否被創建。您正在檢查'$ the_object-> the_attribute'的返回值,錯誤消息意味着'$ the_object'不是一個對象,而是'undef'。如果你包含更多的代碼(比如'$ the_object'來自哪裏,以及它應該具有的屬性),我可以優化我的答案。 – simbabque

回答

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是一個方法(即像一個函數)返回的對象的特定部分的數據。根據類的實現(對象的構建計劃),如果未設置該屬性(初始化爲),則可能只是返回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_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 
} 

可以使用$_isa$_can從安全::伊薩用同樣的方法。


1)是的,該方法與$開始,這的確是一個變量。如果你想了解更多關於如何和爲什麼這個工程,請看mst的談話You did what?

+0

我現在看到我誤解/混淆了原始錯誤消息,因爲它應該與一個(不存在的)對象相關,並且與該方法無關。非常感謝您的詳細解釋! – keeg

相關問題