2017-01-07 13 views
1

オブジェクトが作成されたかどうかをチェックしようとしたときに(「PerlモジュールBio :: Perlによって」)、「未定義の値にメソッド 'xxxx'を呼び出すことができません。オブジェクトの属性に値があるかどうかをチェックする方法は?

属性に値があるかどうかを確認する一般的な方法はありますか?

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; 
    } 
} 

... 
+0

いいえ。objが作成されているかどうかは確認していません。 '$ the_object-> the_attribute'の戻り値をチェックしています。エラーメッセージは' $ the_object'がオブジェクトではなく 'undef'であることを意味します。 ( '$ the_object'がどこから来たのか、そしてそれが持っていると思われる属性のような)もう少しのコードを含めると、私は自分の答えを洗練することができます。 – simbabque

答えて

6
if ($the_object->the_attribute) { 

方法the_attributeの戻り値がtrueの場合にチェックします。 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_objectthe_attributeアクセサーメソッドと呼んでいることがわかりました。従って$the_objectundefです。


何かが真の値を持っているかどうかを確認する最も簡単な方法は、ちょうどifにそれを置くことです。しかし、あなたはすでにそれを知っているようです。

if ($obj) { 
    # there is some non-false value in $obj 
} 

これで、$objが真であることが確認されました。だから、それは目的である可能性があります。だから今あなたの方法を呼び出すことができます。

if ($obj && $obj->the_attribute) { ... } 

この

$objの真ネスをチェックして、 $objで何かがある場合にのみ続行されます。そうでない場合は、 &&の右側を決して呼ぶことはなく、エラーは発生しません。

しかし、$objがメソッドを持つオブジェクトであるかどうかを知りたい場合は、canを使用できます。 アトリビュートは、オブジェクト内に格納されている値のアクセサメソッドに過ぎないことに注意してください。 $objがない場合

if ($obj->can('the_attribute')) { 
    # $obj has a method the_attribute 
} 

しかし、それは爆破することができます。

$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)はい、方法は$で始まる、それは本当に変数です。この方法とその理由についてもっと知りたい場合は、You did what?のmstでトークをご覧ください。

+0

元のエラーメッセージが(存在しない)オブジェクトに関連していて、メソッドに関係してはいけないと誤解されたり混乱したりしていました。あなたの完全な説明に多くの感謝! – keeg

関連する問題