Как проверить, имеет ли атрибут объекта значение?

Я получаю сообщение об ошибке, например, "не могу вызвать метод" xxxx "для неопределенного значения" при попытке проверить, был ли создан объект (модулем perl Bio::Perl).

Существует ли общий способ проверки, имеет ли атрибут значение или нет? Я хотел бы сделать что-то вроде:

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

...

1 ответ

Решение
if ($the_object->the_attribute) {

Это проверяет, если возвращаемое значение метода the_attribute правда. Истина означает, что это не 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_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-объекте.

$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) Да, метод начинается с $ это действительно переменная. Если вы хотите узнать больше о том, как и почему это работает, посмотрите доклад, который вы сделали? по местному времени

Другие вопросы по тегам