* Синтаксис * 


Пел программа (скрипт) состоит из последовательности деклараций и предложений.
Единственно что должно быть обязательно декларировано это форматы отчетов
и подпрограммы (функции). Все не объявленные переменные, массивы, имеют
значение 0 или null.



Пел имеет свободный формат. Комментарии начинаются с символа '#' и
продолжаются до конца строки.
Декларации могут использоваться в любом месте программы так же как и
предложения (statements) но действуют они только в фазе компиляции
программы. Обычно их помещают или в начале или в конце программы.
Декларация подпрограмм позволяет использовать имя подпрограммы
как списковый оператор начиная с момента декларирования.

Пример:
	sub test;	# Декларация подпрограммы test

	$var1 = test $0; # Использование как оператора списка.

Декларации подпрограмм могут быть загружены из отдельного файла
предложением require или загружено и импортировано в текущую
область имен предложением use. Подробно см. главу Модули.




Простое предложение обязательно
заканчивается символом ';' если только это не последнее предложение
в блоке где ';' можно опустить. Заметьте что существуют операторы
такие как eval{} и do{} которые выглядят как сложные предложения
но на самом деле это термы и требуют обязательного указания конца
предложения.

Любое простое предложение может содержать single модификатор
перед ';'. Существуют следующие single модификаторы:

	if EXPR
	unless EXPR
	while EXPR
	until EXPR

где EXPR - выражение возвращающее логическое значение true или false.
Модификаторы while и until вычисляются в начале предложения кроме блока do который выполняется первым.

if EXPR		- Модификатор "если". Предложение выполняется если EXPR возвращает true.

Пример:
	$var = 1;
	$var2 = 3 if $var > 0; # Результат: $var2 = 3

while EXPR	- Модификатор "пока". Предложение выполняется столько раз пока EXPR = true

Пример:
	$var = 1;
	print $var++ while $var < 5; # Печать $var с инкрементом

Результат: 1234


until EXPR	- Модификатор "до ". Предложение выполняется  до тех пор пока EXPR = false

Пример:
	$var = 1;
	print $var++ until $var > 5; # Печать $var с инкрементом

Результат: 12345

unless EXPR	- Модификатор "если не" . Обратный к if. Выражение выполняется есле EXPR = false.

Пример:
	$var = 1;
	print $var++ unless $var > 5; # Печать $var с инкрементом

Результат: 1




Последовательность простых предложений ограниченная функциональными
ограничителями называется блоком. В Пел это может быть
целый файл, последовательность предложений в операторе eval{} или
чаще всего это множество простых предложений ограниченных круглыми
скобками '{}'.

Сужествуют следующие виды сложных предложений:

	if (EXPR) BLOCK
	if (EXPR) BLOCK else BLOCK
	if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK

	LABEL while (EXPR) BLOCK
	LABEL while (EXPR) BLOCK continue BLOCK
	LABEL for (EXPR; EXPR; EXPR) BLOCK
	LABEL foreach VAR (LIST) BLOCK
	LABEL BLOCK continue BLOCK

Обратите внимание, что сложные предложения описаны в термах блоков
а не предложений как в языках C или Pascal. Поэтому необходимо
всегда использовать круглые скобки для обозначения блока.

if (EXPR) BLOCK		- Вычисляется логическое выражение EXPR и если true  блок выполняется.

Пример:
	$var =1;
	if ($var == 1)
	   { print $var,"\n";
	   }
Результат: 1


if (EXPR) BLOCK else BLOCK2	-  Если EXPR=true выполняется BLOCK иначе BLOCK2.

Пример:
	$var =2;
	if ($var == 1)
	   { print "\$var = 1\n";
	   }
	else
	   { print "\$var не равно 1\n";
	   }

Результат: $var не равно 1

if (EXPR1) BLOCK1 elsif (EXPR2) BLOCK2 ... else BLOCK	-
	Если EXPR1=true выполняется BLOCK1 иначе если EXPR2=true выполняется
	BLOCK2 иначе ... иначе BLOCK.

Пример:
	$var = 1;
	if ($var == 0)
	   { print "\$var = 0\n";
	   }
	elsif ($var == 1)
	   { print "\$var = 1\n";
	   }
	else
	   { print "Не известное \$var\n";
	   }

Результат: $var = 1

Цикл while выполняет BLOCK до тех пор пока EXPR = true. Метка LABEL не
обязательна и состоит из идентификатора завершающегося символом ':'.
Метка необходима при использовании внутри блока цикла управляющих
операторов next, last и redo. Если метка все же отсутсвует то
эти операторы ссылаются к началу ближайшего цикла.
Блок после continue выполняется всегда перед тем как вычисляется
логическое выражение EXPR. Это подобно EXPR3 в предлжении for
поэтому в этом блоке удобно изменять счетчики и флаги цикла даже
если применяестя оператор next.



next	- подобен continue в С. Переходит к началу текущего цикла
	т.е. повторяет итерацию.

Пример:
	M1:
	while ($i < 6)
	    {
	    ++$i;	# Увеличиваем счетчик на 1
	    next M1 if $i < 3; # Переходим в начало если $i < 3
	    ++$i;	# иначе увеличиваем счетчик еще раз на 1
	    }
	continue
	    {
	    print "$i "; # Печатаем $i
	    }

Результат: 1 2 4 6

last	- подобен оператору break в языке С. Немедленно прерывает цикл.
	Блок continue пропускается.

Пример:
        M1:
        while ($i < 6)
            {
            ++$i;       # Увеличиваем счетчик на 1
            last M1 if $i > 3; # Выход из цикла если $i > 3
            ++$i;       # иначе увеличиваем счетчик еще раз на 1
            }
continue {
            print "$i "; # Печатаем $i
}

Результат: 2 4

redo	- начать новый цикл не вычисляя EXPR и не выполняя continue блок.

Пример:
        M1:
        while ($i < 6)
            {
            ++$i;       # Увеличиваем счетчик на 1
            redo M1 if $i == 3; # Далее пропустить для $i = 3
            ++$i;       # иначе увеличиваем счетчик еще раз на 1
            }
continue {
            print "$i "; # Печатаем $i
}

Результат: 2 5 7




	LABEL for (EXPR1; EXPR2; EXPR3) BLOCK
Оператор for полностью аналогичен оператору for в С. В перед началом
цикла выполняется EXPR1, если EXPR2 = true выполняется блок, затем
выполняется EXPR3.

Пример:
	for ($i = 2; $i < 5; ++$i)
           {
           print $i, " ";
           }
        print "\nПосле цикла i = $i\n";

Результат:
	2 3 4
	После цикла i = 5



	LABEL foreach VAR (LIST) BLOCK

Переменной VAR присваивается поочередно каждый элемент списка LIST
и выполняется блок. Если VAR опущенно то элементы присваиваются
встроеной переменной $_. Если в теле блока изменять значение VAR
то это вызовет изменение и элементов списка т.к. VAR фактически
указывает на текущий элемент списка.
Вместо слова foreach можно писать просто for - это слова синонимы.

Пример:
        @месяц = ("январь","февраль","март");  # Создали массив
        foreach $i (@месяц)
            {
            print $i," ";       # Печать $i
            }

Результат: январь февраль март

Пример:
        @месяц = ("январь","февраль","март");  # Создали массив
        foreach $i (@месяц)
            {
            $i = uc($i); # Перевели в верхний регистр
            }
        print @месяц;

Результат: ЯНВАРЬФЕВРАЛЬМАРТ

Пример:

	for $i (3,5,7)
	    {
	    print "$i ";
	    }
Результат: 3 5 7




Блок не зависимо от того имеет он метку или нет семантически
представляет собой цикл который выполняется один раз. Поэтому
действие опраторов цикла next, last, redo - аналогично описанному
выше. Блоки удобны для построения switch (переключатель) структур.
В пел нет специального оператора switch подобного языку С поэтому
вы сами можете создавать удобные для вас конструкции. Опыт автора
показывает что для простоты написания лучше всего подходит
конструкция вида if ... elsif ... else ... хотя можно сочинить
и нечто подобное:

	SWITCH:
	{
	if ($i ==1 ) { .....; last SWITCH; }
	if ($i ==2 ) { .....; last SWITCH; }
	if ($i ==3 ) { .....; last SWITCH; }
	$default = 13;
	}

Выбирайте сами по своему вкусу.




В Пел существует оператор goto хотя где , как и когда его применять
как говорил Ходжа Насредин "Тонкий филосовский вопрос".
Для начинающих программистов которым от так "нужен" я бы вообще
посоветовал "забыть" о его существовании. Однако при создании
больших производственных задач на последнем этапе особенно
при отработке "отвальных" ошибочных ситуаций конечно goto нужен.

В Пел реализовано три формы goto. goto - метка, goto - выражение
и goto - подпрограмма.

goto - метка выполняет непосредственный переход на указанную метку.

goto - выражение - Вычисляет имя метки и делает соответсвующий переход.
	Например если мы хотим сделать переход на одну из трех меток
	"M1:", "M2:" или "M3:" в зависимости от значений переменной
	$i равной 0, 1 или 2 то это лучше сделать следующим образом:

	goto ("M1", "M2", "M3")[$i];

	здесь $i используется как индекс массива указанного непосредственно
	в выражении.

goto подпрограмма - довольно редкий случай т.к. всегда проще и надежней
вызвать подпрограмму "естественным" образом.



В Пел реализован очень удобный механизм для написания документации
в момент создания программы. Для этого применяются специальные POD операторы.
Если в теле программы интерпретатор встречает оператор начинающийся
с символа '=' например:

	= head Набор стандартных процедур

то пропускается все до слова '=cut'. Это удобно для включения
длинных на несколько строк или страниц комментариев. Затем
с помощью специальной программы pod можно отделить текст
документации от текста программы.

Last-modified: Thu, 24-Apr-97 18:07:56 GMT