| Содержание | Предисловие | Введение | Ссылки
| Глава 1 | Глава 2 | Глава 3 | Глава 4 | Глава 5 | Глава 6 | Глава 7 | Глава 8 | Глава 9 | Глава 10
| Глава 11 | Глава 12 | Глава 13 | Глава 14 | Глава 15 | Глава 16 | Глава 17 | Глава 18 | Глава 19
| Приложение А | Приложение Б | Приложение В | Приложение Г |

Глава 18

    В этой главе:


Преобразование других программ в Perl-программы

Преобразование awk-программ в Perl-программы

Одна из самых замечательных особенностей Perl состоит в том, что он представляет собой семантическое надмножество (как минимум) языка awk. С практической точки зрения зто значит, что если вы можете сделать что-либо в awk, вы сможете сделать зто и в Perl. При зтом, однако, Perl не обладает синтаксической совместимостью с awk. Например, переменная NR (номер входной записи) awk представляется в Perl как $.

Если у вас ╨сть а^-программа и вы хотите выполнить ее Perl-вариант, можно осуществить механическое Преобразование зтой программы с помо-щью утилиты а2р, которая ╨сть в дистрибутиве Perl. Зта утилита конвертирует синтаксис awk в синтаксис Perl и может создать непосредственно выполняе-мый Perl-сценарий для подавляющего большинства ои^-программ.

Чтобы воспользоваться утилитой а2р, поместите свою aw/^-программу в отдельный файл и вызовите а2р с именем зтого файла в качестве аргумента или переадресуйте стандартный ввод а2р на ввод из зтого файла. В результате на стандартном виводе а2р вы получите нормальную Perl-программу. Например:

$ cat myawkprog

Bb.SIN { sum = 0 )

/llama/ ( sum += $2 )

END { print "The llama count is " sum }

$ a2p <myawkprog >myperlprog $ perl myperlprog somefile The llama count is 15 $

Можно также направить стандартний вывод a2p прямо в Perl, потому что интерпретатор Perl принимает программу со стандартного ввода, если полу-чает такое указание:

$ a2p <myawkprog I perl - somefile

The llama count is 15

$

Преобразованный для использования в Perl aw^-сценарий, как правило, выполняет идентичную функцию, часто с большей скоростью й, конечно, без каких-либо присущих awk ограничений на длину строки, количество параметров и т.д. Некоторые преобразованные Perl-программы могут выпол-няться медленнее; Perl-действие, зквивалентное данной awA-операции, не обязательно будет самым зффективным Perl-кодом, по сравнению с напи-санным вручную.

Вы, возможно, захотите оптимизировать Преобразованный Perl-код или добавить в Perl-версию программы новьге функциональные возможности. Зто сделать довольно просто, поскольку полученный Perl-код читается достаточно легко (учитывая, что перевод выполняется автоматически, сле-дует отметить зто как большое достижение).

В некоторых случаях перевод не выполняется механически. Например, сравнение "меньше чем" и для чисел, и для строк в awk выражается операцией <. В Perl для строк используется it, а для чисел ≈ операция <. В большинстве случаев awk, как и утилита a2p, делает разумное предполо-жение относительно числового или строкового характера двух сравниваемых значений. Однако вполне возможно, что о каких-нибудь двух значеннях будет известно недостаточно много для того, чтобы определить, какое должно выполняться сравнение ≈ числовое или строковое, позтому a2p использует наиболее вероятную операцию и помечает возможно ошибочную строку знаками #?? (Perl-комментарием) и пояснением. После преобразо-вания обязательно просмотрите результат на предмет наличия таких коммен-тариев и проверьте сделанные предположения. Более подробно о работе утилиты a2p рассказывается на ее man-странице. Если зтой утилиты в том каталоге, откуда вы вызываете Perl, нет, громко пожалуйтесь тому, кто инсталлировал вам Perl.

Преобразование sed-программ в Perl-программы

Может быть, вам покажется, что мы повторя╨мся, но угадайте, что мы сейчас скажем? А вот что: Perl ≈ семантическое надмножество не только awk, но и sed.

С дистрибутивом поставляется конвертор sed-Рет╡, который называется s2p. Как и а2р, s2p получает со стандартного ввода ,уе</-сценарий и направляет на стандартний вывод Perl-программу. В отличие от результата работы а2р, преобразованная программа редко ведет себя не так, как нужно, позтому вы вполне можете рассчитывать на ее нормальную работу (при отсутствии дефектов в самой s2p или Perl).

Конвертированные 5╙й/-программы могут работать быстрее или медлен-нее оригинала. Как правило, они работают значительно быстрее (благодаря хорошо оптимизированным Perl-программам обработки регулярних виражений).

Конвертированный waf-сценарий может работать с опцией -п или без нее. Опция -п имеет тот же смысл, что и соответствующий ключ для sed. Чтобы воспользоваться зтой опцией, конвертированный сценарий должен направить сам себя в препроцессор С, а зто несколько замедляет запуск. Если вы зна╨те, что всегда будете вызывать конвертированный wdf-сценарий с опцией -п или без нее (например, при преобразовании wfif-сценария, используемого в больших shell-программах с известными аргументами), вы можете информировать утилиту s2p об зтом (посредством ключей -п и -р), и она оптимизирует сценарий под выбранный вами ключ.

В качестве примера, демонстрирующего високую универсальность и мощь языка Perl, отметим тот факт, что транслятор s2p написан на Perl. Если вы хотите увидеть, как Ларри программирует на Perl, взгляните на зтот транслятор ≈ только сначала сядьте, чтобы не упасть (даже с учетом того, что зто очень древний код, относительно не изменившийся с версии 2).

Преобразование shell-сценариев в Perl-программы

Вы, наверное, подумали, что речь пойдет о конверторе, осуществляющем Преобразование shell-сценариев в Perl-программы?

А вот и нет. Многие спрашивают о такой программе, но проблема в том, что большинство из того, что делает сценарий, делается отнюдь не им самим. Большинство сценариев shell тратят практически все сво╨ время на вызовы отдельных программ для извлечения фрагментов строк, сравнения чисел, конкатенации файлов, удаления каталогов и т.д. Преобразование такого сценария в Perl требовало бы понимания принципа работы каждой из вызываемых утилит или перекладывания вызова каждой из них на плечи Perl, что абсолютно ничего не дает.

Позтому лучшее, что вы можете сделать, ~ зто посмотреть на сценарий shell, определить, что он делает, и начать все с нуля, но уже на Perl. Конечно, вы можете провести на скорую руку транслитерацию ≈ поместив основные части исходного сценария в вызовы system () или заключив их в обратные кавычки. Возможно, вам удастся заменить некоторые операции командами Perl: например, заменить system(rm /red) на unlink (fred) или цикл for shell на такой же цикл Perl. В большинстве случаев, однако, вы увидите, что зто несколько напоминает конвертирование программы, написанной на Коболе, в С (почти с тем же уменьшением количества символов й, как следствие, повышением степени неразборчивости текста программы).

Упражнение

Ответ см. в приложении А.
1. Преобразуйте следующий сценарий shell в Perl-программу:

cat /etc/passwd I

awk -F: '(print $1, $6(' |

while read user home

do

newsrc="$home/.nevsrc" if [ -r $newsrc ] then

if grep -s "'сотр\.lang\.perl\.announce: ' $newsrc then

echo -n "$user is a good person, ";

echo "and reads comp.lang.perl.announce!" fi fi done




|     Назад     |     Вперед     |


| Содержание | Предисловие | Введение | Ссылки
| Глава 1 | Глава 2 | Глава 3 | Глава 4 | Глава 5 | Глава 6 | Глава 7 | Глава 8 | Глава 9 | Глава 10
| Глава 11 | Глава 12 | Глава 13 | Глава 14 | Глава 15 | Глава 16 | Глава 17 | Глава 18 | Глава 19
| Приложение А | Приложение Б | Приложение В | Приложение Г |