Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование скриптов на Perl'e (Выпуск №5)


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Программирование скриптов на Perl'e (выпуск 5).


Здравствуйте дорогие мои подписчики.


Сегодня в выпуске:




Несколько слов перед началом

После выхода четвертого выпуска рассылки ко мне пришло одно довольно интересное письмо.   И я хочу ответить на него на страницах рассылки.

Текст письма следующий:

Hello vitalij,

    Я думаю, неправильно, что Вы не упомянули в разделе для начинающих,
среди операторов проверки условий, такую часто применяемую конструкцию,
как  "УСЛОВИЕ or ОПЕРАТОР;", УСЛОВИЕ || ОПЕРАТОР;", "УСЛОВИЕ and ОПЕРАТОР;",
"УСЛОВИЕ && ОПЕРАТОР;" и тому подобные...

    Конструкция elsif не такая уж оригинальная, так как используется во многих
языках в том же смысле и абсолютно спокойно воспроизводится и в Паскале, и в С.

    То, что операторы for и foreach взаимозаменяемы лучше было написать при
первом их упоминании.

    А что Вы имеете против использования модуля CGI для разбора параметров,
куков и т.п. задач? Почему Вы упоминаете его вскользь, и сами продолжаете
пользоваться самоделками? Это чем-то оправдано? может и мне стоит?

--
Best regards,
 NeNashev                          mailto:nashev@mail.ru
Теперь по порядку отвечу на все вопросы и утверждения из этого письма.

Во-первых я не считаю, что "...такую часто применяемую конструкцию, как "УСЛОВИЕ or ОПЕРАТОР;", "УСЛОВИЕ || ОПЕРАТОР;", "УСЛОВИЕ and ОПЕРАТОР;", "УСЛОВИЕ && ОПЕРАТОР;" и тому подобные..." можно отнести к операторам проверки условий.   На мой взгляд, они относятся к логическим операторам, и когда в рассылке дойдет до этого речь, то я обязательно расскажу об их использовании.

Во-вторых, "Конструкция elsif не такая уж оригинальная ... и абсолютно спокойно воспроизводится и в Паскале, и в С" я, конечно же, согласен с Вами, что эту конструкцию можно заменить следующей:

        if (УСЛОВИЕ1)
          {  БЛОК1
          }
        else if (УСЛОВИЕ2)
          {  БЛОК2
          }
        ...
        else
          {  БЛОКN
          }
но при этом я не считаю, что от того, что конструкция elsif заменяема она теряет свою оригинальность.

В-третьих, да, операторы for и foreach взаимозаменяемы, но так как они не были декларированы как один, да и синтаксисом немного различаются, то, на мой взгляд, лучше использовать каждый из них в том виде, в котором он был разработан.   А фраза о том, что "Вместо слова foreach можно писать просто for - это слова синонимы" была просто констатацией такой возможности.

Ну и, наконец, последнее.   Лично я ничего не имею "... против использования модуля CGI для разбора параметров, куков и т.п. задач ...", но моя рассылка, как Вы могли заметить, называется "Программирование скриптов на Perl'e" а не "Использование модулей Perl'а". И в ней я пытаюсь объяснить: ЧТО нужно сделать, КАК и самое главное - ПОЧЕМУ это так делается.   Я противник обучения типа: "Напишите такую-то строку (команду) и у Вас все заработает".   И в качестве "самоделок" я использую реальный рабочий код, на его примере объясняя, что нужно сделать и как это будет работать.   Это оправдано, на мой взгляд, тем, что человек не знакомый с работой таких функций видит перед собой не только вызов функции, которая что-то делает, а видит, что именно она делает.   И, кроме того, я не уверен, что функция разбора ReadParse справится с русскими символами.

Стоит ли Вам так пробовать - не знаю, каждый сам решает, что ему нужно.

Ну а теперь, пожалуй, мы перейдем к изучению Perl'а. И сегодняшние темы:

  • Perl для начинающих - Регулярные выражения
  • CGI-программирование - Регистрация с подтверждением




    Perl для начинающих - Регулярные выражения

    Регулярные выражения - это образец, состоящий из символов.   Скрипты на языке Perl используют символьные образцы для того, чтобы провести анализ входных данных, расщепляя их на части.   Часто скрипт может проанализировать входные данные, основываясь на пробелах, запятых, символах табуляции и других разделителях.   Но когда входные данные имеют произвольный формат то лучше всего с такой задачей справляются регулярные выражения.

    Синтаксис регулярных выражений

    Для сокращения размеров регулярных выражений, в Perl'е использует специальные символы.   Ниже приведен список некоторых символов, используемых скриптами языка Perl в регулярных выражениях.
    Символ Описание
     .  Один любой символ (за исключением символа новой строки);
    (..)  Группирует последовательность элементов;
    +  Удовлетворяет предыдущему образцу один или большее количество раз;
    ?  Удовлетворяет образцу нуль или один раз;
    *  Соответствует образцу один или нуль раз;
    [...]  Соответствует символу из заданного множества;
    [^...]  Соответствует символу из множества, полученного отрицанием;
    (...|...|...)  Соответствует одной из альтернатив;
    ^  Соответствует началу строки;
    $  Соответствует образцу в конце строки;
    {n, m}  Соответствует образцу от n до m раз;
    {n}  Соответствует образцу точно n раз;
    {n,}  Соответствует образцу минимум n раз;
    \n\t и т. д.  Соответствует знаку новой строки, символу табуляции и т. д. (все спецсимволы);
    \b  Соответствует границе слова;
     Соответствует не границе слова;
    \d  Соответствует цифре;
    \D  Соответствует не цифре;
    \s  Соответствует пробелу;
    \S  Соответствует не пробелу;
    \w  Соответствует букве, цифре или символу '_';
    \W  Соответствует символу, не являющемуся ни буквой, ни цифрой, ни '_';

    В Perl'е регулярные выражения (образцы, шаблоны) помещаются в слэши, например, в виде /pattern/.   Следующий фрагмент программы иллюстрирует регулярные выражения языка Perl:

    # эти регулярные выражения возвращают значение "истина", если:
    /ig/                 # строка содержит 'ig'
    /(b|d|f)ig/          # строка содержит 'big', 'dig' или 'fig'
    /[0-9]+/             # строка содержит цифры
    /[A-Za-a0-9]{6, 9}/  # строка содержит от 6 до 9 букв или цифр
    

    Использование регулярных выражений для поиска по ключевым словам

    В скриптах на Perl'е используют регулярные выражения для упрощения сравнение строк.   Для того чтобы проверить, содержит ли строка заданный образец, регулярные выражения можно использовать следующим образом:
            if ($str=~/pattern/)
              {  БЛОК
              }
    
    В данном случае регулярные выражения принимают значение "истина", если образец найден в строке $str.   Если строка не содержит образца, то выражение возвращает значение "ложь".   Например, следующее выражение проверяет, содержит ли строка слово Perl:
            if ($str=~/Perl/)
              {  print "Строка содержит слово Perl.\n";
              }
            else
              {  print "Слово Perl в строке отсутствует.\n";
              }
    
    но этот пример найдет слово Perl и в следующих строках:
  • Perler;
  • DiPerl;
  • kejnhclejkcnelPerlhgfcbksjdb;
    и вообще в любом слове, среди символов которого встретится такая комбинация.

    Но решение такой проблемы не должно вызвать у Вас затруднений.   Достаточно взглянуть на приведенный ранее список специальных символов и сразу станет ясно, что нам необходим символ, обозначающий границу слова - т. е. '\b'.

    Теперь проверка будет выглядеть так:

            if ($str=~/\bPerl\b/)

    Использование регулярных выражений для анализа входных данных

    По мере усложнения Ваших скриптов возникнет много случаев, когда вы захотите узнать больше, чем просто проверить, совпадает ли образец со строкой или нет.   Например, может потребоваться, извлечь определенное значение из строки.

    Используя символы группировки () внутри регулярного выражения, скрипт может извлечь соответствующие образцу значения из строки и сформировать из них список.   Например, следующий фрагмент программы использует регулярные выражения для того, чтобы извлечь месяцы, дни и годы из строки:

            $str="Сентябрь 27, 2000";
            ($m, $d, $y) = $str=~/\s*(\S*)\s+(\d+)\D+(\d{4})/;
    
    Прежде, чем разбирать, как это работает, хочу спросить Вас: "Не удивляют ли Вас два знака '=' в одной строке?"   Надеюсь, что не удивляет, т. к. второй знак это не "равенство", а "сопоставление с образцом" - '=~'.   И кроме этого, в данном случае мы фактически присваиваем списку находящемуся в левой части выражения - ($m, $d, $y) результат сопоставления с шаблоном, т. е. список ($1, $2, $3).

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

  • Пропустить вначале любой специальный символ;
  • Записать все символы, не являющиеся специальными, в переменную $m (переменная для записи месяца);
  • Пропустить специальный символ;
  • Поместить все цифры в переменную $d (переменная для записи числа);
  • Пропустить все знаки, не являющиеся цифрами;
  • Записать четыре цифры в переменную $у (переменная для записи года).

    Perl поддерживает также другую форму сравнения с образцом, использующую оператор, который добавляет отрицание результата: !~.   Этот оператор эквивалентен выражению:

            !($str=~/pattern/).

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

    До сих пор мы использовали только операторы, проверяющие строки на соответствие образцу.   Но Perl поддерживает два других регулярных выражения, которые модифицируют проверяемую строковую переменную.   В записанной дальше инструкции происходит замена части строки, которая соответствует образцу, на заданную строку:
            $str=~s/PATTERN/REPLACEMENT/;
    Например, следующая инструкция заменит слово "colour" на "color":
            $str=~s/\bcolour\b/color/;
    Небольшая модификация позволяет заменить все вхождения слова "colour" на "color":
            $str=~s/\bcolour\b/color/g;
    Теперь о том, что это и как работает.

    Оператор s/PATTERN/REPLACEMENT/egimosx производит поиск строки, соответствующей шаблону PATTERN и если строка найдена, то подставляет на ее место текст REPLACEMENT.   При этом возвращается количество произведенных подстановок.   Если перед этим оператором не использовался оператор =~ или !~ для определения переменной, которая будет обрабатываться, то будет модифицироваться переменная $_.

    Этот оператор используется со следующими опциями:
    Символ Описание
    e  интерпретирует правую часть как выражение;
    g  производит подстановку на место каждой строки, соответствующей шаблону (глобальный поиск);
    i  производит поиск, без различия регистра букв;
    m  обрабатывает строку, как многострочную (содержащую символы перевода строки);
    o  происходит подстановка только на место первой встреченной строки;
    s  обрабатывает строку, как состоящую только из одной строки;
    x  использует расширенные регулярные выражения.

    Для замены множества символов в строке поиска используются следующие операторы:

  • tr/SEARCHLIST/REPLACEMENTLIST/cds;
  • y/SEARCHLIST/REPLACEMENTLIST/cds.

    Они заменяют все найденные символы из множества символов SEARCHLIST на соответствующие символы из множества символов REPLACEMENTLIST.   Возвращает число символов, которые были заменены или удалены.   Если посредством операторов =~ или !~ не была указана никакая строка, то обрабатывается переменная $_.   Оператор y является синонимом tr. Если SEARCHLIST заключен в скобки, то REPLACEMENTLIST тоже заключается в скобки, которые могут отличаться от тех, в которые заключается шаблон, например:

            tr[A-Z][a-z]
            tr(+-*/)/ABCD/
    
    Эти операторы употребляется со следующими опциями:
    Символ Описание
    c  заменяет символы, которые не входят во множество SEARCHLIST на REPLACEMENTLIST, например:
     tr/a-zA-Z/ /c; - заменит все неалфавитные символы пробелами;
    c  Стирает символы, которые ни на что не заменяются;
    s  Переводит последовательность символов, которые заменяются на один и тот же символ в один символ, например:
     $a='CCCCCCCCC';
     $a=~tr/C/D/s;
     теперь $a='D'

    На сегодня все. Удачных Вам поисков и замен.




    CGI-программирование - Регистрация с подтверждением

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

    И здесь есть несколько путей. Первое, что приходит в голову - это сохранить информацию в файл, для последующего ее использования. Кроме этого можно на основе полученных данных создать новый HTML-документ и отправить его обратно клиенту, приславшему запрос. А можно сделать еще что-нибудь. Тут все зависит только от Вашей фантазии, ну и естественно от необходимости.

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

    Для начала напишем небольшую HTML-страничку, которая будет предлагать пользователю ввести свои фамилию, имя, отчество, возраст и телефон:

    <html>
    
    <head>
      <title>Ввод данных формы</title>
    </head>
    
    <body>
    <form action="http://www.domain.ru/cgi-bin/register.cgi" method=post>
      <div align="center">
        <h2>Регистрация</h2>
        Заполнить, пожалуйста, все расположенные ниже поля<br>
        <p>
        <table border=0 align="center">
          <tr>
            <td width=100>Фамилия</td>
            <td width=300>
              <input type="text" name="SecName" size=40 maxlength=40>
            </td>
          </tr>
          <tr>
            <td width=100>Имя</td>
            <td width=300>
              <input type="text" name="FirstName" size=40 maxlength=40>
            </td>
          </tr>
          <tr>
            <td width=100>Отчество</td>
            <td width=300>
              <input type="text" name="MiddName" size=40 maxlength=40>
            </td>
          </tr>
          <tr>
            <td width=100>Возраст</td>
            <td width=300>
              <input type="text" name="Age" size=40 maxlength=40>
            </td>
          </tr>
          <tr>
            <td width=100>Телефон</td>
            <td width=300>
              <input type="text" name="Phone" size=40 maxlength=40>
            </td>
          </tr>
        </table>
        <p>
        <input type="reset" value="Очистить">
        <input type="submit" value="Отправить">
      </div>
    </form>
    </body>
    
    </html>
    
    Эта страничка будет делать запрос, и отправлять его на сервер скрипту под названием register.cgi.

    Запись в файлы

    Одно из действий, которое Вы можете совершить над данными, это записать их в файл. Perl предоставляет набор функций для открытия, обработки и закрытия файлов. Таким образом, Вы можете создать новый HTML документ, добавить данные в уже существующий HTML документ или сохранить данные в текстовом файле для дальнейшей обработки.

    Перед осуществлением запись в файл, вы должны убедиться, что web-сервер имеет доступ к директории, в которой находится файл и имеет права на запись в этот файл.

    Обратите внимание: функция close должна располагаться как можно ближе к последней функции записи в файл. Это обусловлено тем, что web-сервер выполняется в многопользовательской среде, и скрипт может запускаться одновременно несколькими пользователями. При открытии файла на запись он (файл) блокируется и другие экземпляры скрипта не смогут его открыть, что вызовет задержку в выполнении запроса.

    Запись в существующий файл проста, когда Вы хотите добавить новую информацию в конец файла. Например, для добавления данных о новом пользователе в файл Вам потребуется следующий фрагмент кода:

         # Определяем переменную, содержащую путь к лог-файлу
    $LOG_DIR='/home/name/public_html/data/config/';
    
         # Определяем переменную, содержащую имя лог-файла
    $LOG_FILE='register.log';
    
         # Создадим полный путь к лог-файлу
    $FullPath=$LOG_DIR.$LOG_FILE;
    
         # Открываем файл, используя идентификатор LOGF
    if (!open(LOGF, ">>$FullPath"))     # Открываем для добавления
      {  $mess="Невозможно открыть файл \"$LOG_FILE\" ($!).";
         &Error($mess);      # Вызов подпрограммы обработки ошибки
      }
    else
      {  $newlines="Фамилия: ".$FORM{SecName}."\n";
         $newlines.="Имя: ".$FORM{FirstName}."\n";
         $newlines.="Отчество: ".$FORM{MiddName}."\n";
         $newlines.="Возраст: ".$FORM{Age}."\n";
         $newlines.="Телефон: ".$FORM{Phone}."\n";
         print LOGF "---------- New User ----------\n";
         print LOGF $newlines;
         close (LOGF);
      }
    
    В результате работы этой части скрипта у Вас в лог-файле добавится новая запись.

    Создание web-страниц "на лету"

    Следующей важной частью скрипта является посылка результата обратно пользователю. Это достигается тем же оператором print, но без идентификатора файла или канала. Все, что печатается на стандартный выход, формирует текущий документ в окне браузера.
    print <<END_HTML;
    Content-type: text/html
    
    <html>
    
    <head>
      <title>CGI-генерированная форма</title>
    </head>
    
    <body>
    <div align="center">
      <h2>Регистрация завершена</h2>
      <p>Поздравляем Вас, $FORM{FirstName} $FORM{MiddName}, с удачной регистрацией.
    </div>
    </body>
    
    </html>
    END_HTML
    
    Здесь используется так называемый HERE-документ. Т. е. весь текст, находящийся между оператором print <<END_HTML; и признаком окончания блока - END_HTML выведется в том виде в котором он записан.

    Обратите внимание на строку "Content-type: text/html". Эта строка содержит информацию о типе возвращаемых данных. Пустая строка после нее при этом обязательна. Она отделяет заголовок типа от самого HTML-документа. Эта страница будет возвращена пользователю почти сразу после нажатия им кнопки Submit.

    Учтите, что это всего лишь один из многих примеров того, какой может быть страница "на лету". В принципе Вы можете формировать HTML документ любой формы и содержания.

    Отправка данных по e-mail

    Иногда Вам может потребоваться, чтобы данные, введенные в форму, были посланы по некоторому адресу электронной почты. Для этого вам потребуется программа посылки почты с интерфейсом командной строки. Под UNIX это может быть sendmail или mail. В данном примере данные посылаются с помощью программы sendmail.
    $to="admin\@domain.ru";
    open (MAIL, "|/usr/bin/sendmail -t");
    print MAIL "From: Web-сервер\n";
    print MAIL "To: $to\n";
    print MAIL "Subject: Новый пользователь";
    print MAIL "Content-Type: text/plain; charset=Windows-1251\n";
    print MAIL "Кто-то воспользовался формой регистрации.";
    print MAIL "Вот что он ввел:";
    print MAIL "Фамилия: ",$FORM{'SecName'},"\n";
    print MAIL "Имя: ",$FORM{'FirstName'},"\n";
    print MAIL "Отчество: ",$FORM{'MiddName'},"\n";
    print MAIL "Возраст: ",$FORM{'Age'},"\n";
    print MAIL "Телефон: ",$FORM{'Phone'},"\n";
    close (MAIL);
    

    А теперь полный текст скрипта register.cgi

    #!/usr/bin/perl
    
    $LOG_DIR='#/home/name/public_html/data/config/';
    $LOG_FILE='register.log';
    
    %FORM=();
    $mess='';
    
    ($result, $mess)=&GetFormInput;   # произвели разбор запроса
    &Error($mess) if ($result==0);    # если неудачно - сообщение
    
         # Сохраним данные пользователя в лог-файле
    $FullPath=$LOG_DIR.$LOG_FILE;
    if (!open(LOGF, ">>$FullPath"))   # Открываем для добавления
      {  $mess="Невозможно открыть файл \"$LOG_FILE\" ($!).";
         &Error($mess);
      }
    else
      {  $newlines="Фамилия: ".$FORM{SecName}."\n";
         $newlines.="Имя: ".$FORM{FirstName}."\n";
         $newlines.="Отчество: ".$FORM{MiddName}."\n";
         $newlines.="Возраст: ".$FORM{Age}."\n";
         $newlines.="Телефон: ".$FORM{Phone}."\n";
         print LOGF "---------- New User ----------\n";
         print LOGF $newlines;
         close (LOGF);
      }
    
         # Сгенерируем ответ
    print <<END_HTML;
    Content-type: text/html
    
    <html>
    
    <head>
      <title>CGI-генерированная форма</title>
    </head>
    
    <body>
    <div align="center">
      <h2>Регистрация завершена</h2>
      <p>Поздравляем Вас, $FORM{FirstName} $FORM{MiddName}, с удачной регистрацией.
    </div>
    </body>
    
    </html>
    END_HTML
    
         # Отправим письмо администратору
    $to="admin\@domain.ru";
    open (MAIL, "|/usr/bin/sendmail -t");
    print MAIL "From: Web-сервер\n";
    print MAIL "To: $to\n";
    print MAIL "Subject: Новый пользователь";
    print MAIL "Content-Type: text/plain; charset=Windows-1251\n";
    print MAIL "Кто-то воспользовался формой регистрации.";
    print MAIL "Вот что он ввел:";
    print MAIL "Фамилия: ",$FORM{'SecName'},"\n";
    print MAIL "Имя: ",$FORM{'FirstName'},"\n";
    print MAIL "Отчество: ",$FORM{'MiddName'},"\n";
    print MAIL "Возраст: ",$FORM{'Age'},"\n";
    print MAIL "Телефон: ",$FORM{'Phone'},"\n";
    close (MAIL);
    
              # Подпрограммы
    
         # Подпрограмма вывода сообщения об ошибке
    sub Error
    {  local($message)=$_[0];
    
       print "Content-type: text/html\n\n";
       print "<HTML>\n";
       print "<HEAD><TITLE>Error Page</TITLE></HEAD>\n";
       print "<BODY>\n";
       print "<B>$message</B>\n";
       print "</BODY>\n";
       print "</HTML>\n";
       exit 0;
    }
    
         # Подпрограмма разбора входного запроса
    sub GetFormInput
    {  local($name, $value, $buffer, $err, $pair, @pairs);
    
       $err="Разбор запроса завершен.";
       if ($ENV{'REQUEST_METHOD'} eq 'GET')
         {  @pairs=split(/&/, $ENV{'QUERY_STRING'});
         }
       elsif ($ENV{'REQUEST_METHOD'} eq 'POST')
         {  read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
            @pairs=split(/&/, $buffer);
         }
       else
         {  $err="Метод запроса не опознан.  Используйте GET или POST.";
            return(0, $err);
         }
       foreach $pair (@pairs)
         {  ($name, $value)=split(/=/, $pair);
            $value=~tr/+/ /;
            $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ge;
            $FORM{$name}=$value;
         }
       return(1, $err);
    }
    
    За сим на сегодня заканчиваю.




    Наши друзья

    Дорогие подписчики! Если Вы еще не заглядывали на сайт наших друзей "InfoCity - виртуальный город компьютерной документации" (http://www.infocity.kiev.ua), то Вам обязательно стоит там побывать.

    Очень грамотно организованный сервер компьютерной документации.   Не пугайтесь титульного листа и ныряйте внутрь.   Количество книжек в электронном виде потрясает и радует.

    Здесь Вы можете сразу и подписаться на регулярные новости библиотеки.   Для этого просто вставьте Ваш e-mail в соответствующее поле, ну и конечно же не забудьте нажать на кнопочку "OK", и все. :-))

    Рассылки Subscribe.Ru
    Новости компьютерной библиотеки InfoCity

    Адрес рассылки "Новости компьютерной библиотеки InfoCity" в Каталоге subscribe.ru: http://subscribe.ru/catalog/comp.paper.infocity/

    Архив рассылки "Новости компьютерной библиотеки InfoCity" находится на subscribe.ru по адресу: http://subscribe.ru/archive/comp.paper.infocity/

    InfoCity - виртуальный город технической документации.




    О рассылке

    В связи с тем, что ко мне часто приходят письма вновь подписавшихся с просьбой выслать предыдущие номера рассылки или указать где их можно взять, я даю адреса на subscribe.ru связанные с моей рассылкой.

    Домашняя страница этой рассылки в Каталоге subscribe.ru: http://subscribe.ru/catalog/comp.soft.prog.perlprog/, здесь же Вы можете и подписаться на данную рассылку.

    Архив этой рассылки находится на subscribe.ru по адресу: http://subscribe.ru/archive/comp.soft.prog.perlprog/

    Данная рассылка распространяется только через subscribe.ru.

    Если Вам понравилась эта рассылка, и Вы считаете, что она может быть полезна и другим, то отправьте ее своим друзьям.




    Обращение к рекламодателям

    Уважаемые господа!   Если Вы хотите разместить свою рекламу на страницах этой рассылки, то обращайтесь со своими предложениями к ее автору, то есть ко мне, по адресу vitalij@newmail.ru и я сообщу Вам дополнительные сведения.




    Ну, на этом позвольте на сегодня закончить.   До новых встреч.


    Виталий Ярошевский vitalij@newmail.ru


    При подготовке данной рассылки были использованы следующие материалы:

    1. "Спецификация языка Perl"     Алена Федосеева
    2. "Введение в Perl" Андрей Новиков


    P. S.   Кстати буквально несколько дней назад, а именно 27.09.2000 исполнился ровно один месяц с момента открытия рассылки, с чем я Вас всех, ну и себя заодно поздравляю.



    http://subscribe.ru/
    E-mail: ask@subscribe.ru

    В избранное