Как работает elsif в Perl?

Почему в Perl есть «elsif», а не «elseif»?

Я делаю что-то вроде этого:

$somevariable = 0;
if ($idcount==5) 
{
    # Do something
    if (somestatement is true) # 1 
    {
        $somevariable = 1;
    }
}
elsif ($idcount > 1 && somevariable = 0)
{
    # Do something else here
}

Код никогда не приходит к оператору elsif. В этом случае idcount на самом деле равно 5, поэтому речь идет о первом операторе if. Но внутреннее утверждение if (1) неверно, поэтому $somevariable по-прежнему равно 0. Поскольку idcount равно 5, оно также должно прийти к elsif, поскольку $idcount больше 1, а $somevariable по-прежнему равно 0.

Может быть, я просто устал и не вижу чего-то очевидного.


person Community    schedule 18.03.2009    source источник
comment
Пожалуйста, вырежьте и вставьте, не перепечатывая. Когда вы перепечатываете, вы не только потенциально решаете свою настоящую проблему, не замечая ее, но и представляете другие, которые затем отвлекают людей от возможности помочь вам.   -  person ysth    schedule 19.03.2009


Ответы (9)


Нет, что-либо в elsif имеет шанс быть выполненным только в том случае, если ни одно из предыдущих условий if/elsif не было истинным, это "else" его часть.

Если вы хотите, чтобы оценивались оба, просто сделайте if вместо elsif.

person Chad Birch    schedule 18.03.2009

elsif ($idcount > 1 && somevariable = 0)

Должно быть:

elsif ($idcount > 1 && $somevariable == 0)

Оператор присваивания возвращает присвоенное значение, 0, что соответствует ложному, поэтому логическое и '&&' всегда терпит неудачу.

person spoulson    schedule 18.03.2009
comment
Конечно, это так. Ошибка не позволяет elsif достичь этого блока кода. Остальной код выглядит идеально. - person spoulson; 18.03.2009
comment
Нет, это отдельная проблема. Styris ожидал, что код войдет в блок if, а затем выйдет оттуда и войдет в блок elsif. - person Chad Birch; 18.03.2009
comment
Не забудьте $ перед переменной. - person Barry Brown; 18.03.2009

Вот как книга лам отвечает на вопрос elsif vs elseif:

— Потому что так сказал Ларри.

person Chuck Phillips    schedule 18.03.2009

В любой конструкции if-elsif-else вы всегда выполняете только первую ветвь, условие которой истинно. Как только эта ветвь выполняется, программа запускается после всего if-elsif-else.

Если вы хотите сделать что-то с возможными несколькими ответвлениями, вы можете создать свой собственный синтаксис, похожий на регистр, с несколькими блоками if. Существует конструкция given-when из Perl 5.10, но она перешла в экспериментальный статус и может быть удалена из языка.

Что касается написания elsif, здесь есть несколько факторов.

На Си ты пишешь

if( ... ) {
   ... }
else if ( ... ) {

Иногда это вызывает проблему «зависания». Если вы начали, но не закончили вставлять if-else if прямо перед другим, но отличным, if, вы объединили их через оборванное else. Ларри Уоллу это не понравилось, поэтому он объединил «иначе, если» в одно слово «иначе, если». исправил это, удалив букву «e», чтобы получилось просто «elsif».

person brian d foy    schedule 19.03.2009
comment
Стена, требующая блоков, а не простых операторов, полностью решила проблему оборванного else, верно? Я думаю, что вопрос ОП, возможно, спрашивал, почему Уолл решил не делать грамматику просто IfStmt ::= 'if' '(' Exp ')' Block ('else' 'if' '(' Exp ')' Block)* ('else' Block)? Я не понимаю, почему это не сработало бы, и почему могли возникнуть какие-либо еще проблемы. У вас есть секунда, чтобы уточнить? Вы просто говорите, что может быть более высокая вероятность опечатки? - person Ray Toal; 12.05.2015
comment
Вы все еще можете забыть добавить блок для else и запустить его в другую структуру if. - person brian d foy; 12.05.2015
comment
Спасибо за разъяснения. Хотя это немного натянуто. Была ли это действительно причина, которую назвал Уолл? Будет ли программист действительно писать if (e) {something} else, а затем просто останавливаться на этом и оставлять несколько пустых строк, а затем следовать за этим другим оператором if? Я не вижу в этом ничего правдоподобного, но мы говорим о Perl, так что кто знает (ИЗВИНИТЕ!). Мое собственное предположение состоит в том, что Уоллу не нравилась LL(2)-ность else if (elsif делает его LL(1)), но если вы из первых рук знаете обоснование Уолла, тогда отличный ответ! - person Ray Toal; 13.05.2015
comment
Речь шла о C. Может быть какой-то код был удален для создания висящего еще, или не полностью вставлен, или еще какие-то причины. - person brian d foy; 13.05.2015

Я не понимаю, какое у вас замешательство связано с тем фактом, что Perl использует «elsif», а не «else if» или «elseif». На каждом языке, который я когда-либо использовал, от FORTRAN в стиле до 1970-х годов до Java и включая попутно такие «изюминки», как Easytreive, если вы делаете «if cond ... else ...», то материал после else не не будет выполнен, если исходное "условие" истинно. Вот что значит "еще".

В вашем случае "cond" равен "($idcount==5)", что вы уже заявили, верно, а другая часть, которая не выполняется, потому что это правда, - это "if ($idcount > 1 && $somevariable == 0)...".

person Paul Tomblin    schedule 18.03.2009

В Perl есть elsif, потому что Perl не допускает "else if" в стиле C без скобок. Вместо этого вам нужно будет иметь что-то вроде:

if (x) {

}
else {
  if(y) {

  }
}
person Plasmer    schedule 19.03.2009

«elsif» в Perl работает точно так же, как «elseif», «else if» и «elif» в других языках. Это просто вопрос правописания.

person Barry Brown    schedule 18.03.2009

Вот эквивалент того, что было опубликовано в вопросе.

use strict;
use warnings;

$somevariable = 0;
if ($idcount==5) 
{
  # do something
  if ( 1 )
  {
    $somevariable = 1;
  }
}
else
{
  if ($idcount > 1 && somevariable == 0) # this line was wrong in the question
  {
    # do something else here
  }
}

or

use Modern::Perl;

$somevariable = 0;
given($idcount){
  when( 5 ){
    # do something
    if ( 1 ){
      $somevariable = 1;
    }
  }
  when( $_ > 1 && $somevariable == 0 ){
    # do something else here
  }
}

use Modern::Perl; совпадает с use strict; use warnings; use 5.010;

person Brad Gilbert    schedule 18.03.2009

Если вы собираетесь использовать if...elsif на любом языке, ваши условия должны быть взаимоисключающими. Два условия в вашем примере могут выполняться одновременно, поэтому вы должны разбить его на два отдельных оператора if.

person Bill the Lizard    schedule 18.03.2009