2014-09-03 2 views
1

я наследовать много кода, как в следующемизменить поведение «если» заявление в Perl немного

if (func1()) { .... } 

The «func1()» может возвращать скаляр, массив или ссылку на массив. Я хотел бы оценку «если» в приведенном выше в следующем виде:

  • , когда func1() возвращает массив, он должен оценить, чтобы быть правдой, если есть, по меньшей мере, один элемент в массиве
  • , когда Функция func1() возвращает ссылку на массив, она должна оцениваться как истина, если в указанном массиве имеется хотя бы один элемент.
  • когда func1() возвращает скаляр, просто оценить его как обычный

Я знаю, что может сделать что-то вроде следующего

@a = func1(); 
if (!defined $a[0]) { 
    #false 
} elsif (ref($a[0] eq "ARRAY") { 
    if (scalar(@{$a[0]})) { 
     #true 
    } else { 
     #false 
    } 
} elsif ($a[0]) { 
    #true 
} else { 
    #false 
} 

Но это утомительно, и есть много такого вхождения в if (func1())... , Интересно, есть ли простой способ заставить оператор perl «if» вести себя так, как я хочу.

Заранее спасибо.

Обновление:

Благодаря вопрос @ikegami «s, я понял, что моя реальная проблема заключается в следующем (см комментарий в следующем, воспроизведен здесь, чтобы сделать его легко читать)

funcX() вернет ссылку на список. Текущее поведение if заключается в том, что он всегда будет оцениваться как истинный независимо от того, пуст ли список ссылок или нет. Но я бы хотел, чтобы if (funcX()) оценивал значение false, если ссылочный список пуст и имеет значение true.

+0

Возможно, сам 'func1' должен быть изменен, чтобы возвращать логическое значение при вызове в скалярном контексте. Если вы не можете этого сделать, рассмотрите функцию-оболочку для перевода результата. –

+0

@Wumpus, спасибо, что указали его. К сожалению, в моей ситуации есть много функций, таких как func1 («func1» - просто пример). Было бы здорово, если бы я мог немного изменить поведение «если». – packetie

+0

1) Невозможно вернуть массив. Только список скаляров может быть возвращен субмаринами. В скалярном контексте это дополнительно ограничивается ровно одним скаляром. – ikegami

ответ

2
sub check($) { 
    return undef if !$_[0]; 
    return undef if (ref($_[0]) || '') eq 'ARRAY' && [email protected]{ $_[0] }; 
    return 1; 
} 

if (check(func1()) { 
    ... 
} 

Как и в исходном коде (и наоборот, что вы сказали), func1 должна возвращать скаляр. check return false, если скаляр является ложным, false, если скаляр является ссылкой на пустой массив и true в противном случае. (Точно так же, как ваша слишком сложная проверка, которая не компилируется и может вызывать предупреждение, когда func1 возвращает истинное значение, которое не является ссылкой.)

+0

Кстати, слишком много вхождений 'if (funcX()) ...', хотел бы «волшебный» способ изменить поведение «if» для достижения этого :-) – packetie

+0

Действительно?!? Используйте замену регулярного выражения! – ikegami

+0

Невозможно использовать регулярное выражение по нескольким причинам. Один из них: 'funcX (...)' имеет сложные параметры, и регулярное выражение не может его уловить. Кажется, что теоретически perl intepreter может поддержать это: если значение ссылается на список, то используйте размер ссылочного списка как способ принятия решения. – packetie

Смежные вопросы