Модуль HTML::Phl для обработки HTML-документов, содержащих инструкции с кодом Perl

от автора

    В статье приведена спецификация модуля HTML::Phl для работы с HTML-документами, содержащими код языка программирования Perl.

    Задача модуля HTML::Phl — выбрать из текстового документа формата HTML, размещенный в нем особым образом perl-код, выполнить кое-какие манипуляции над ним и остальным кодом, объединить полученное в единый код perl и «скормить» всё это ‘eval‘, получая на выходе сгенерированную HTML-страницу, воспроизводимую веб-браузером.

Пример

1   <HTML> 2   <HEAD> 3   <META content="text/html; charset=UTF-8" http-equiv="Content-Type"> 4   <TITLE>Пример PHL</TITLE> 5   </HEAD> 6    7   Создаем два дочерних процесса f1 и f2<br> 8 9   %pl  include("process_win.phl", "fork decode=cp1251", "f1"); 10  %pl  include("process_utf.phl", "fork decode=utf8", "f2"); 11 12  Ждем завершения процессов<br> 13 14  <%pl my %join = include("JOIN", "f1 f2"); %> 15 16  Результаты выполнения процессов<br> 17 18  <%pl 19     foreach my $key(keys(%join)) { 20        if (ref $join{$key}) { 21           print "процесс '$key' - результат: "; 22           for (my $i = 0; $i <= $#{$join{$key}}; $i++) { 23              print "'${$join{$key}}[$i]' "; 24           } 25           print "<br>"; 26        } else { 27           print "процесс '$key' - результат: '$join{$key}'<br>"; 28        } 29     } 30  %> 31    32  </HTML> 

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


Оглавление:

Спецификация PHL
    • Указатели
    • Разделители
    • Ключи
    • Функции
    • Модули-расширения
    • Конфигурационные настройки
Дистрибутив PHL

Спецификация PHL  ^ 

    В HTML документе perl-код размещается с помощью своеобразных инструкций. У каждой такой инструкции есть начало и конец, позволяющие идентифицировать код perl в документе.
    В спецификации PHL определено три варианта написания инструкций:

1. Линейная инструкция:
   %pl [keys] [perl code]

2. Инструкция в виде однострочного блока:
   <%pl[(:|=)[name]] [keys] [perl code] %>

3. Многострочный блок:
   <%pl[(:|=)[name]] [keys]
      [perl code]

   %>

где
    ‘%pl‘, ‘<%pl‘, ‘%>‘ — указатели инструкции (определяют начало и конец кода Perl);

    [name] — имя блока (используется при идентификации блоков, преимущественно при параллельном программировании);

    ‘:‘ или ‘=‘ — разделители (с одной стороны являются разделителями между указателями инструкции и именем блока, с другой стороны, обладают рядом дополнительных функциональных особенностей);

    [keys] — управляющие ключи (позволяют видоизменять код Perl, заключенный в инструкции, перед тем как его передать интерпретатору на выполнение);

    [perl code] — код Perl.

Примеры

  %pl print sqrt(2);    <%pl print $var; %>      <%pl= $var; %>      <%pl       foreach my $key(keys(%ENV)) {          print "$key — $ENV{$key}<br>";       }   %> 

    Управляющие элементы [name] и [keys] используются не так часто, и с успехом можно обойтись и без них, но их использование бывает весьма удобным.

  <%pl:f1 -fork      # Код дочернего процесса      my $f = "Данные дочернего процесса f1";      sleep 1;      return $f;   %>      <%pl -join=f1      # Результат дочернего процесса f1      print $phl_join{f1};   %> 

    К стандартным функциям Perl в PHL дополнительно добавлена функцияinclude()‘), реализованная для возможности сборки документа из нескольких файлов.

  %pl include($file_name);         <%pl include("$file_name", "socket"); %>    <%pl      my $result = include("$file_name", "open decode");   %> 

Указатели  ^ 

    По умолчанию указатели имеют вид: ‘<%pl‘, ‘%>‘ и ‘%pl‘.
    Указатели можно переопределить в настройках файла ‘Phl.pm‘ или в конфигурационном файле ‘config.phl‘. В результате, можно написать так <% …code perl… %> или так [ …code perl… ] или даже вoт так ¦ …code perl… ¦.

    При желании можно определить свои собственные (дополнительные) указатели инструкций. Это реализуется с помощью специально оформленных модулей.

    К примеру, с помощью модуля ‘HTML::Phl::Php‘ в дополнение к указателю инструкции ‘<%pl‘ добавляется указатель ‘<%php‘, позволяющий выполнить простой код языка программирования PHP.

 1  %pl -ev use HTML::Phl::Php;  2    3  <%php  4    echo "PHP >> <b>OK</b><br>";  5    echo date('H:i:s d.m.Y');  6  %> 

Результат

PHP >> OK
14:23:22 26.12.2016

Разделители ^ 

    Задача разделителей — отделить указатель инструкции от имени блока.
    В отличие от разделителя ‘:‘, разделитель ‘=‘ изменяет в анализаторе интерпретацию кода. При этом, результат применения разделителя ‘=‘ в однострочном и многострочном блоках различаются.

 1  %pl  my $test = "<b>тест</b>";  2    3  1. Переменная '<%pl= $test %>' внутри однострочного блока.  4  <br><br>  5    6  <%pl=name1  7     2. Переменная '$test' внутри  8     многострочного блока '<b>$phl_blok[1]</b>' (разделитель '=').  9  %>  10  <br><br>  11    12  <%pl:name2  13     print "3. Переменная '$test'";  14     print "внутри многострочного блока '<b>$phl_blok[2]</b>' (разделитель ':').";  15  %> 

Код после анализатора

 1  my $test = "<b>тест</b>";  2  print <<'[HTML]';  3     4  [HTML]  5  print <<'[HTML]' =~ /(.*)/;  6  1. Переменная '  7  [HTML]  8  print($test);  9  print <<'[HTML]';  10  ' внутри однострочного блока.  11  [HTML]  12  print <<'[HTML]';  13  <br><br>  14     15  [HTML]  16  print <<"[HTML]";  17     2. Переменная "$test" внутри  18     многострочного блока "<b>$phl_blok[1]</b>" (разделитель "=").  19  [HTML]  20  print <<'[HTML]';  21  <br><br>  22     23  [HTML]  24     print "3. Переменная '$test'";  25     print "внутри многострочного блока '<b>$phl_blok[2]</b>' (разделитель ':')."; 

Результат

1. Переменная ‘тест‘ внутри однострочного блока.

2. Переменная ‘тест‘ внутри многострочного блока ‘name1‘ (разделитель ‘=’).

3. Переменная ‘тест‘внутри многострочного блока ‘name2‘ (разделитель ‘:’).

Ключи ^ 

    Ключи позволяют видоизменять код perl, размещенный в инструкциях. Их можно указывать в полном или в сокращенном виде:
        -begin
        -end
        -perl_all
        -eval
        -fork
        -thread
        -join

• Ключи ‘-begin‘ [ ‘-bg‘ ] и ‘-end

    При использовании ключа ‘-begin‘ анализатор берет код perl, содержащийся в инструкции, и оборачивает его блоком ‘BEGIN {}‘.
    То же самое происходит при использовании ключа ‘-end‘ — код perl помещается в блок ‘END {}‘.

    Исходный код:

 1  1. Текст HTML<br>  2  <%pl -end  3     print "2. Первый end<br>";  4  %>  5  3. Текст HTML<br>  6    7  <%pl -begin  8     print "4. Первый begin<br>";  9  %>  10 5. Текст HTML<br>  11    12 <%pl -end  13    print "6. Второй end<br>";  14 %>  15 7. Текст HTML<br>  16    17 <%pl -bg  18    print "8. Второй begin<br>";  19 %>  20 9. Текст HTML<br> 

Результат

4. Первый begin
8. Второй begin
1. Текст HTML
3. Текст HTML
5. Текст HTML
7. Текст HTML
9. Текст HTML
6. Второй end
2. Первый end

• Ключ ‘-perl_all‘ [ ‘-pl‘ ]

    При использовании данного ключа, отпадает необходимость ограничивать код perl указателями инструкций. Анализатор будет воспринимать весь текст документа, как Perl-код.

 1  %pl -pl  2    3  use CGI;  4    5  print "Content-type: text/html; charset=utf-8\n\n";  6    7  my $test = "Текст";  8  my $q = new CGI;  9    10  print $q -> h4("$test из модуля CGI");  11  print ("<H4>$test из Phl</H4>"); 

Результат

Текст из модуля CGI

Текст из Phl

• Ключ ‘-eval‘ [ ‘-ev‘ ]

    Ключ позволяет выполнить код, заключенный внутри инструкции, в процессе работы анализатора (перед его выполнением eval).
    Например, попробуем с помощью данного ключа изменить указатели ‘&lt%pl‘ и др., разместив в коде следующую инструкцию:

 1  <%pl -eval  2    $phl{lt} = '[';  3    $phl{rt} = ']';  4    $phl{ln} = '~';  5    $phl{sh} = '';  6  %> 

    Указатели инструкций приобрели совершенно другой вид. Теперь инструкцию можно написать таким вот образом:

 1  [=  2    Многострочный блок  3  ] 

    или таким

 1  [ print "Однострочный блок" ] 

    или таким

 1  ~ print "Линейная инструкция" 

• Ключ ‘-fork‘ [ ‘-fk‘ ]

    Код, заключенный внутри инструкции, выполняется в параллельном дочернем процессе, созданном в результате запуска fork().

 1  <%pl:f1 -fork  2    # Код дочернего процесса с именем f1  3    my $f;  4    sleep 1; # Параллельная обработка данных процессом f1  5    return $f;  6  %> 

• Ключ ‘-thread‘ [ ‘-td‘ ]

    Код, заключенный внутри инструкции, выполняется в параллельном потоке («нити», «ветке» процесса), созданном стандартным модулем ‘threads‘ в рамках одного процесса.

 1  <%pl:t1 -thread  2    # Код нити с именем t1  3    my $t;  4    sleep 1; # Параллельная обработка данных нитью t1  5    return $t;  6  %> 

• Ключ ‘-join‘ [ ‘-jn‘ ]

    Ключ дает возможность получить результаты выполнения дочерних процессов и нитей.
    Результаты размещаются в хэше %phl_join, ключами которого являются имена создаваемых процессов/потоков. Если при обращении за результатом нужные параллельные процессы ещё не завершились, программа ждет их завершения.

 1  <%pl -join  2    # Результаты выполнения параллельных дочерних процессов и потоков  3    foreach my $key(keys(%phl_join)) {  4        if (ref $phl_join{$key}) {  # если значение - ссылка  5          my @result = @{$phl_join{$key}};  6          print "процесс '$key' - результат первого аргумента '$result[0]'";  7        } else {  8          print "процесс '$key' - результат '$phl_join{$key}'";  9        }  10    }  11  %> 

• Дополнительные ключи

    При желании можно определить свои собственные (дополнительные) ключи или переопределить существующие. Это реализуется с помощью специально оформленных модулей.
    Так, к примеру, с помощью модуля ‘HTML::Phl::Utilit‘ и ключа ‘-import‘ [ ‘-im‘ ] можно просмотреть список всех указателей, ключей и параметров, в данный момент доступных программе.

 1  %pl -ev use HTML::Phl::Utilit;  2    3  %pl -import 

Результат

1. HTML::Phl::Php
    • param:
        — php
    • sh:
        — php
2. HTML::Phl::Psimple
    • param:
        — Simple
        — sl
3. HTML::Phl::Result
    • param:
        — result
4. HTML::Phl::Ru
    • sh:
        — рус
5. HTML::Phl::Utilit
    • eval:
        — analys
        — as
        — listing
        — lt
    • include:
        — CONFIG
        — TIMER
    • key:
        — analys
        — as
        — cf
        — config
        — im
        — import
        — listing
        — lt
        — no_timer
        — nt
        — timer
        — tm
    • param:
        — listing
        — lt

Функции ^ 

    В PHL добавлена всего одна функция ‘include()‘, реализованная для возможности сборки документа из нескольких файлов, содержащих HTML (TXT) или PHL разметку.
    Функция ‘include()‘ похожа на стандартную Perl функцию ‘open()‘, с тем отличием, что первым аргументом является имя включаемого в документ файла, а вторым — один или несколько специальных управляющих параметров.

 1  %pl include($file_name);  2       3  <%pl include("$file_name", "socket"); %>  4    5  <%pl  6     my $result = include($file_name, "open decode");  7  %> 

    В общем случае, написание функции ‘include()‘ выглядит так:

    include("file_name" [, "param" [, "name_process"]]);

file_name:
    «file_name.phl»
    «file_name.cgi»
    «file_path/file_name.phl»
    "/file_path/file_name.html"
    «httр://domain/file_path/file_name.html»

[param]:
    phl,   exist,   head
    abs,   no_abs,   no_eval
    no_strict,   open,   decode
    no_decode,   cgi,   socket
    fork,   thread

дополнительные параметры и зависимости:
    phl [.phl] <= exist, head, abs, decode
    cgi [.cgi] <= require, decode
    open <= decode, abs
    socket <= exist, head, no_abs, decode, no_decode
    fork <= waitpid, no_waitpid
    thread <= join, detach

    Первый аргумент ‘file_name‘ кроме имени файла может содержать зарезервированные слова "JOIN", "CONFIG" или "TIMER".
    Если файл ‘file_name‘ имеет расширение ‘.phl‘, то такой файл идентифицируется, как файл формата PHL. Расширение может быть изменено в настройках с помощью $phl{pl}.
    При вызове функции ‘include()‘ в неопределенном контексте результат выполнения кода Perl помещается в тело документа внутри функции print(). При скалярном или списковом контексте результат возвращается в виде запрашиваемого значения переменной или списка значений соответственно.

 1 <%pl  2    include("file_name.phl");  3    my $result = include("file_name.phl");  4    my @result = include("file_name.phl");  5 %> 

    Второй аргумент функции ‘include()‘ может содержать один или несколько специальных управляющих параметров.

• Параметр ‘phl

    Данный параметр указывает обработчику, что код, содержащийся в подключаемом файле, представляет собой документ формата PHL.
    Данные файла отправляются в анализатор, где преобразуются в perl-код и передаются ‘eval‘.
    Параметр ‘phl‘ выполняет аналогичные действия, если бы мы в имени включаемого файла просто указали расширение ‘.phl‘ (расширение можно изменить в настройках в ‘$phl{pl}‘).

 1 <%pl  2    include("file_name.txt", "phl");  3    my $result = include("file_name.html", "phl decode=utf-8");  4    my @result = include("file_name", "phl abs");  5 %> 

• Параметр ‘exist‘ (‘ex‘)

    Позволяет проверить существование файла.

 1 <%pl  2    my $exist_file = include("$file_name", "exist");  3    if ($exist_file) {  4        print "Файл $file_name найден";  5    } else {  6        print "Файл $file_name не найден";  7    }  8 %> 

• Параметр ‘head‘ (‘hd‘)

    Возвращает список из 5 элементов: Content type, Document length, Modified time, Expires, Server.

 1 <%pl  2    my @head = include("$file_name", "head");  3 %> 

• Параметр ‘abs

    Если присутствует параметр ‘abs‘, осуществляется преобразование относительных ссылок, указанных в файле, в абсолютные.

 %pl include("$file_name", "abs"); 

• Параметр ‘no_eval‘ (‘ne‘)

    При указании данного параметра результат выполнения кода включаемого файла игнорируется.

 <%pl include("$file_name", "no_eval") %> 

• Параметр ‘no_strict‘ (‘ns‘)

    Если указан параметр ‘no_strict‘, то на код загружаемого файла ‘$file_name‘ действие прагмы ‘use strict‘ не распространяется.

 1 <%pl  2    include("$file_name", "ns");  3 %> 

• Параметр ‘open‘ ( ‘on‘ )

    Как и функция ‘open()‘, служит для открытия файла и извлечения из него каких-либо данных (возможность записи данных в файл отсутствует).

 1 <%pl  2    include("$file_name", "open");  3    my $result = include("$file_name", "open decode=koi8-r");  4    my @result = include("$file_name", "on, decode=cp1251, abs");  5 %> 

• Параметр ‘decode‘ (‘dc‘)

    При наличии параметра ‘decode‘ данные из указанной в параметрах кодировки (к примеру, ‘decode=cp1251‘) декодируются во внутренний формат Perl.
    Если кодировка не указана или отсутствует параметр ‘decode‘, то при декодировании подразумевается, что кодировка включаемого файла соответствует $phl{encoding_in}, указанной в настройках phl.pm (или config.phl).
    Если кодировка результирующего документа отлична от ‘utf-8‘, то дополнительно осуществляется кодирование данных в кодировку $phl{encoding_out}, указанную в настройках phl.pm (или config.phl).
    Кодирование и декодирование данных осуществляется с использованием стандартного модуля ‘Encode.pm‘.

• Параметр ‘cgi

    Данный параметр предназначен для подключения cgi-скриптов, написанных на Perl.

 1 <%pl  2    include("file_name.cgi");  3    include("$file_name", "cgi");  4    include("$file_name", "cgi require");   5    include("file_name.cgi", "decode=cp866");  6 %> 

• Параметр ‘socket‘ (‘sk‘)

    Применяется для загрузки web-документа с помощью стандартного модуля ‘IO::Socket::INET

 1 <%pl  2    include("file_name.html", "socket");  3    include("http://domain/");  4    my $text = include("http://domain/file_path/file_name.html", "decode=cp1251");  5    my @result = include("$file_name", "decode no_abs");  6 %> 

    Если адрес включаемого в документ файла начинается с http или ftp, то указывать параметр ‘socket‘ не обязательно.
    Совместно с параметром ‘socket‘ могут применяться дополнительные параметры ‘exist‘, ‘head‘, ‘no_abs‘, ‘decode‘, ‘no_decode‘.

  • дополнительный параметрexist‘ (‘ex‘)

    Позволяет проверить существование домена, файла, адреса.

 1  <%pl  2     my @include_name_file = (  3        'dir1/name_file.html',  4        '/dir2/name_file.php',  5        'http://www.yandex.ru',  6        'http://www.yandex/eklmnfjoeqxngsitwf.html',  7        'http://eklmnfjoeqxngsitwfhoevd.ru'  8     );  9     10    foreach my $name_file (@include_name_file) {  11       my $ex = include("$name_file", "socket exist");  12       if ($ex) {  13          print "Файл '$name_file' найден<br>";  14       } elsif (!defined $ex) {  15          print "Ресурс '$name_file' не отвечает<br>";     16       } else {  17          print "Файл '$name_file' не найден<br>";  18       }  19    }  20 %> 
  • дополнительный параметрhead‘ (‘hd‘)

    Возвращает заголовок документа

 1  <%pl  2     foreach my $name_file (@test_name_file) {  3        my head = include("$name_file", "socket head");  4        if ($#head) {  5           print "Заголовок от '$name_file' получен => '@head[0..3]'<br>";  6        } else {  7           print "Заголовка от '$name_file' нет => '@head'<br>";  8        }  9     }  10 %> 
  • дополнительный параметрno_abs‘ (‘na‘)

    По умолчанию, все относительные ссылки заменяются на абсолютные, но если указан параметр ‘no_abs‘, то этого не происходит.

  %pl include("$file_name", "socket no_abs"); 
  • дополнительный параметрdecode‘ (‘dc‘)

    Служит для декодирования документов из кодировки, указанной параметром ‘decode‘, во внутренний формат Perl и далее в кодировку, указанную в настройках в $phl{encoding_out}.
    Если параметр ‘decode‘ используется без указания исходной кодировки запрашиваемого файла, то декодирование осуществляется с учетом кодировки, указанной в заголовке файла в ‘charset‘ (при наличии).
    Если параметр ‘decode‘ не используется, по умолчанию подразумевается, что наш файл в кодировке utf-8.
    При использовании параметра ‘no_decode‘ (‘nd‘) никакого декодирования данных не происходит.

 1  <%pl  2     include("http://www.rbc.ru", "decode=utf-8");  3     include("http://www.mail.ru", "decode");  4     my $html_text1 = include("http://ru.motorsport.com");  5     my $html_text2 = include("http://www.google.com", "nd");  6  %> 

• Параметр ‘fork‘ (‘fk‘)

    Код загружаемого файла выполняется в параллельном дочернем процессе, созданном в результате запуска ‘fork()‘.

 1  <%pl  2     include("$file_name", "fork");  3  %> 

    Результат выполнения параллельного процесса можно вернуть в родительский, используя ‘return‘ в тексте инструкции включаемого файла.

 1  <%pl  2     <font color=#646464><I># Код дочернего процесса $phl_var{name}</I></font>  3     my $f = "Передаваемые данные";  4     sleep 1;  5     return $f;  6  %> 

    В третьем аргументе функции ‘include()‘ можно указать уникальное имя дочернего процесса, чтобы затем обратиться за результатом выполнения дочернего процесса «по имени».

 1  <%pl  2     include("$file_name", "fork", "f1");  3  %> 
  • дополнительный параметрwaitpid‘ (‘wd‘)

    Для того, чтобы вернуть результат выполнения дочернего процесса в точку вызова функции ‘include()‘, необходимо дополнительно к параметру ‘fork‘ указать параметр ‘waitpid‘ или в качестве третьего аргумента функции ‘include()‘ указать ‘waitpid‘.
    Результат отработки параллельного процесса можно вернуть обратно в родительский процесс, вызвав ‘include()‘ в скалярном или списковом контексте.

 1  <%pl  2     $result = include("$file_name", "fork waitpid");  3     @result = include("$file_name", "fork", "waitpid");  4  %> 

    На самом деле, можно вообще отказаться от параметра ‘waitpid‘, как во втором так и в третьем аргументе. В таком случае, программа всё равно будет ждать завершения дочернего процесса, а функция ‘include()‘ получается менее громоздкой.

 1  <%pl  2     @result = include("$file_name", "fork", "");  3     $result = include("$file_name", "fk");  4  %> 
  • дополнительный параметрno_waitpid‘ (‘nw‘)

    Результат выполнения процесса вернуть не удастся, если только, не попробовать что-либо записать в файл или вывести на экран.

 1  <%pl  2     include("$file_name", "fork no_waitpid");  3     include("$file_name", "fork", "no_waitpid");  4  %> 
  • аргументJOIN

    Для обращения за результатом выполнения дочернего процесса можно использовать функцию ‘include()‘, где в качестве первого аргумента необходимо указать зарезервированное слово ‘JOIN‘, вторым аргументом — имя или имена дочерних процессов.

 1  <%pl  2     include("$file_name", "fork", "f1");  3      4     # Далее может следовать тело программы с некоторым кодом  5    6     my $rezult = include("JOIN", "f1");  7  %> 

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

 1  <%pl  2     my %join_2_3 = include("JOIN", "f2 f3");   3     print "Результат процесса 'f2' = $join_2_3{f2}<br>";  4    5     my %join_all = include("JOIN");  6     foreach my $key(keys(%join_all)) {  7        if (ref $join_all{$key}) {  8           my @result = @{$join_all{$key}};  9           print "Результат процесса '$key' = '$join_all{$key}' => ";  10          print "и первый разыменованный элемент массива = '$result[0]'<br>";  11       } else {  12          print "Результат процесса '$key' = '$join_all{$key}'<br>";  13       }  14    }  15 %> 

• Параметр ‘thread‘ (‘td‘)

    Создается, так называемая, «нить» («поток») — своеобразная ветка процесса, в которой возможно выполнение кода параллельно коду породившего нить процесса.
    Для создания нити используется стандартный модуль ‘thread‘ (в свою очередь, Perl должен быть настроен на работу с тредами).

 1  <%pl  2     include("$file_name", "thread");  3  %> 

    Как и в случае с параметром ‘fork‘, при использовании нитей существует возможность вернуть результат выполнения созданной нити, как в точку вызова функции ‘include()‘, так и в произвольную точку программы или вообще «забыть» о результате, ничего не возвращая.

  • дополнительный параметрjoin‘ (‘jn‘)

    Результат выполнения нити возвращается в точку вызова, при этом родительский процесс временно прекращает своё выполнение и ждет получения данных (от созданных потоков).

 1  <%pl  2     $result = include("$file_name", "thread join");  3     @result = include("$file_name", "thread", "join");  4     %result = include("$file_name", "thread");  5  %> 
  • дополнительный параметрdetach‘ (‘dh‘)

    Нить создается, но что в ней происходит основная ветка процесса не знает.

 1  <%pl  2     include("$file_name", "thread detach");  3     include("$file_name", "thread", "detach");  4  %> 

    Вернуть данные в любую точку основной ветки процесса можно, присвоив нити имя (по аналогии с дочерним процессом, создаваемым параметром ‘fork‘).

 1  <%pl  2     include("$file_name", "thread", "t1");  3     include("$file_name", "thread", "t2");  4     include("$file_name", "thread", "t3");  5      6     my $rezult = include("JOIN", "t2");  7     print "Результат нити 't2' = '$rezult'<br>";  8    9     my %join = include("JOIN", "t1 t3");   10    print "Результат нити 't1' = '$join{t1}'<br>";  11    print "Результат нити 't3' = '$join{t3}'<br>";  12 %> 

• Собственные параметры

    При желании можно определить свои собственные (дополнительные) параметры или переопределить существующие. Это реализуется с помощью специально оформленных модулей.
    Так, к примеру, с помощью модуля ‘HTML::Phl::Utilit‘ и параметра ‘analys‘ (‘as‘) появляется возможность просмотреть сформированный анализатором код perl включаемого файла перед его выполнением eval.

    пример:

 1  %pl -ev use HTML::Phl::Utilit;  2    3  <%pl  4     include("$file_name", "as");  5  %> 

Листинг

 1  Текст HTML<br>  2    3  <%pl  4     my $test = "Текст Perl<br>";  5     print ("$test");  6  %>  7    8  Текст HTML<br> 

Результат

 1  print <<'[HTML]';  2  Текст HTML<br>  3     4  [HTML]  5     my $test = "Текст Perl<br>";  6     print ("$test");  7  print <<'[HTML]';  8     9  Текст HTML<br>  10  [HTML] 

Модули-расширения PHL ^ 

    Для достижения большей гибкости работы в PHL реализована возможность задавать собственные указатели инструкции [sh], ключи [keys], первый аргумент [include] и параметры [param] функции ‘include()‘.

    <%[sh] [keys]
        …
        include("[include]", "[param]");
        …
    %>

    Новые ключи, параметры и указатели импортируются в phl.pm из специально написанных для данных целей модулей.
    Для примера в PHL включены 4 модуля:

   use HTML::Phl::Utilit;    use HTML::Phl::Psimple;    use HTML::Phl::Php;    use HTML::Phl::Ru; 

    Модули можно подключить как в файле ‘phl.pm‘ или ‘config.phl‘, так и в файле PHL.

 1  %pl -ev use HTML::Phl::Utilit  2    3  <%pl  4     # код perl  5  %> 

• Модуль ‘HTML::Phl::Utilit

    Модуль экспортирует в программу 5 ключей, 2 параметра и 2 аргумента для функции ‘include()‘.

[keys]:
    -listing
    -analys
    -config
    -timer
    -no_timer

[param]:
    listing
    analys

[include]:
    CONFIG
    TIMER

    Ключи-listing‘ [ ‘-lt‘ ] и ‘-analys‘ [ ‘-as‘ ] и параметрыlisting‘ ( ‘lt‘ ) и ‘analys‘ ( ‘as‘ ) дают, возможность просмотреть листинг программы или сформированный анализатором код perl перед его выполнением eval.

    Ключ ‘-listing‘ [ ‘-lt‘ ]

 1  Текст HTML 1  2  <br><br>  3    4  <%pl -lt  5     my $test = "Текст Perl<br>";  6     print "$test";  7  %>  8  <br>  9    10 Текст HTML 2 

Результат

Текст HTML 1

 1   my $test = "Текст Perl<br>";  2   print "$test"; 

Текст HTML 2

    Ключ ‘-analys‘ [ ‘-as‘ ]

 1  %pl -as  2    3  <%pl  4     my $test = "Текст Perl<br>";  5     print ("$test");  6  %>  7    8  Текст HTML и <%pl= $test %> 

Результат

 1  ;  2  print <<'[HTML]';  3     4  [HTML]  5     my $test = "Текст Perl<br>";  6     print ("$test");  7  print <<'[HTML]';  8     9  [HTML]  10  print <<'[HTML]' =~ /(.*)/;  11  Текст HTML и  12  [HTML]  13  print($test); 

    Ключ-config‘ [ ‘-cf‘ ] или аргументCONFIG‘ функции ‘include()‘ выводят на печать хэш %phl конфигурационных переменных.

 1  %pl -config  2    3  или так  4    5  <%pl  6     include("CONFIG");  7  %> 

Результат

Конфигурационные переменные

bottom = »
bufer = ‘1
config = ‘config.phl
config_path = »
encoding_in = ‘utf8
encoding_out = ‘utf8
finde_config = ‘yes
header = ‘Content-type: text/html; charset=utf-8
index = ‘index.phl
ln = ‘%
locale = ‘utf8
lt = ‘<%
pl = ‘phl
rt = ‘%>
script_dir = »
sh = ‘pl
threads = ‘1
timer = ‘0
top = »

    Ключи-timer‘ [ ‘-tm‘ ] и ‘-no_timer‘ [ ‘-nt‘ ] позволяют изменить механизм вывода на экран временных промежутков работы компонентов программы,
а используя аргумент ‘TIMER‘ функции ‘include()‘ можно задать свой таймер.

 1 <%pl  2    # запуск встроенного таймера  3    %pl -timer  4  5    # остановка встроенного таймера  6    %pl -nt  7 %> 

Пример

1. Запускаем timer ключем ‘-timer’ или ‘-tm’
timer = 4

2. Проверяем результат на тестовом ‘include()’ (без параметров)

Результат =>

• Время — 0.248574 [0.226931 ] < INCLUDE_BEGINE ()

• Время — 0.248953 [0.227302 ] < INCLUDE_END ()

test: timer = 4

3. Выключаем timer ключем ‘-no_timer’ или ‘-nt’

4. Проверяем результат на тестовом ‘include()’

Результат => test: timer = 0

 1 <%pl  2    # пример создания своего таймера  3    include("TIMER", "имя таймера");  4 %> 

Пример

Создаем таймер 1

• Время — 0.000005 < TIMER (name_timer_1)

ждем некоторое время — sleep 0.2

• Время — 0.200440 < TIMER (name_timer_1)

Новый таймер 2

• Время — 0.000004 < TIMER (name_timer_2)

ждем некоторое время — sleep 0.5

• Время — 0.701001 < TIMER (name_timer_1)

• Время — 0.500496 < TIMER (name_timer_2)

Новый таймер 3

• Время — 0.000003 < TIMER (name_timer_3)

ждем некоторое время — sleep 0.35

• Время — 1.051648 < TIMER (name_timer_1)

• Время — 0.851139 < TIMER (name_timer_2)

• Время — 0.350579 < TIMER (name_timer_3)

• Модуль ‘HTML::Phl::Php

    Экспортирует указатель ‘php‘, превращая указатель инструкции ‘<%pl‘ в ‘<%php‘, для возможности работы с кодом языка программирования PHP;

 1  %pl -ev use HTML::Phl::Php;  2    3  %pl our $pl = 5;  4    5  Исходная переменная PERL: $pl = <b>'<%pl= $pl %>'</b>.  6  <br><br>  7    8  <%php  9     echo "Значение переменной $pl передаем в PHP ($pl -> $php).<br>";  10    OUT_PERL($pl -> $php);  11     12    echo "<li>Переменная $php = $php.</li><br>";  13    14    echo "В PHP изменяем значение переменной: $php = 2 * $php + 1.5.<br><br>";  15    $php = 2 * $php + 1.5;  16    17    echo "Возвращаем значение переменной $php в PERL ($php -> $pl).<br>";  18    IN_PERL($php -> $pl);  19 %>  20    21  <li>Результирующая переменная PERL: $pl = <b>'<%pl= $pl %>'</b></li>. 

Результат

Исходная переменная PERL: $pl = ‘5’.

Значение переменной $pl передаем в PHP ($pl -> $php).
Переменная $php = 5.
В PHP изменяем значение переменной: $php = 2 * $php + 1.5.

Возвращаем значение переменной $php в PERL ($php -> $pl).
Результирующая переменная PERL: $pl = ‘11.5’.

• Модуль ‘HTML::Phl::Ru

    Экспортирует указатель ‘рус‘, превращая указатель инструкции ‘<%pl‘ в ‘<%рус‘, позволяя работать с некоторыми функциями и операторами кириллического написания.

 1  %pl -ev use HTML::Phl::Ru;  2    3  <%рус  4     my @имена_файлов = (  5        'file_exist.phl',  6        'http://www.pushkinmuseum.ru',  7        'http://www.pushkinmuseum.ru/467899',  8        'http://eklmn12344556778.ru'  9     );  10     11    foreach my $имя_файла (@имена_файлов) {  12       my $найдено = ВКЛЮЧИТЬ("$имя_файла", "socket exist");  13       ЕСЛИ ($найдено) {  14          ПЕЧАТЬ "'$имя_файла' - <B>найден</B><br>";  15       } ИЛИ ЕСЛИ (!defined $найдено) {  16          ПЕЧАТЬ "'$имя_файла' - <B>не отвечает</B><br>";     17       } ИНАЧЕ {  18          ПЕЧАТЬ ("'$имя_файла' - <B>не найден</B><br>");  19       }  20    }  21 %> 

Результат

‘file_exist.phl’ — не найден
‘http://www.pushkinmuseum.ru’ — найден
‘http://www.pushkinmuseum.ru/467899’ — не найден
‘http://eklmn12344556778.ru’ — не отвечает

• Модуль ‘HTML::Phl::Psimple

    Экспортирует параметр ‘Simple‘ [‘sl‘] для работы со стандартным модулем Perl ‘LWP::Simple‘;

Структура модулей-расширений

    Для возможности экспорта ключей, параметров и указателей модули должны размещаться в определенной папке (по умолчанию — в ‘Phl’, находящейся рядом с основным файлом программы ‘phl.pm‘) и содержать двумерный хэш ‘%phl_import‘, в котором ключами второго хеша будут экспортируемые ключи, параметры и указатели.
    Хэш ‘%phl_import‘ может включать 5 ключей — ‘sh‘, ‘key‘, ‘param‘, ‘include‘ и ‘eval‘.

 1    our %phl_import = (  2       key     => {  3                    tm    => \&HTML::Phl::Utilit::key_timer,  4                    im    => \&HTML::Phl::Utilit::print_import,  5                  },  6       include => {  7                    TIMER  => \&HTML::Phl::Utilit::my_timer,  8                    CONFIG => \&HTML::Phl::Utilit::config,  9                  },  10       param  => {lt    => \&HTML::Phl::Utilit::open_listing},  11       sh     => {'рус'  => \&HTML::Phl::Ru::ru_perl},  12       eval   => {as    => \&HTML::Phl::Utilit::eval_code}  13   ); 

Конфигурационные настройки ^ 

    Конфигурационные файлы ‘config.phl‘ позволяют переопределять базовые переменные, указанные в ‘phl.pm‘. Их можно размещать в любой web-директории, содержащей PHL файлы.
    Конфигурационные файлы разрабатываются в формате Perl и содержат значения ключей хеша %phl.

config.phl

# Расширение файлов, обрабатываемых анализатором программы, как файлы формата PHL (по умолчанию принято расширение — ‘.phl’)
     $phl{pl} = ‘phl‘;

# Имя файла, которое ищет функция ‘include()’ в директории, если не указан загружаемый файл, к примеру domain.ru/file_path
     $phl{index} = ‘index.phl‘;

# Осуществлять или не осуществлять поиск конфигурационных файлов ‘config.phl’ в директории загружаемых include() файлов [ yes/no ]
     $phl{finde_config} = "yes";

# Определение указателей инструкций [ по умолчанию, ‘<%pl code_perl %>’, ‘%pl line_code_perl’ ]
     $phl{lt} = ‘<%‘;
# начало блока инструкции
     $phl{rt} = ‘%>‘;
# конец блока инструкции
     $phl{ln} = ‘%‘;
# линейная инструкция
     $phl{sh} = ‘pl‘;
# указатель принадлежности к языковой конструкции (в данном случае к perl)

# Заголовок документа [ к примеру, «Content-type: text/html; charset=utf-8\n\n»; $phl_header = "" — нет заголовка ]
     $phl{header} = "";

# Верхний колонтитул
     $phl{top} = "";

# Нижний колонтитул
     $phl{bottom} = "";

# Сброс буфера [ «1» соответствует => $| = 1, «0» соответствует => $| = 0 ]
     $phl{bufer} = 1;

# Использование потоков (нитей) [ 1/0 ]
     $phl{threads} = 1;

# Подсчитывается время загрузки компонентов [ различная степень детализации => «0» — нет, «1»…«4» — да ]
     $phl{timer} = 0;

# Кодировка файлов [ cp1251, utf8, koi8-r, iso-8859-5, cp866… ]
     $phl{encoding_in} = "utf8"; # кодировка загружаемых include() файлов
     $phl{encoding_out} = "utf8"; # кодировка результирующего документа
     $phl{locale} = "utf8"; # кодировка имен файлов файловой системы


Дистрибутив PHL ^ 

camel
    Модуль ‘HTML::Phl’ вместе с дополнительными модулями-расширениями, тестами и примерами можно скачать здесь.
    При желании опробовать работу модуля в ОС Android, необходимо установить SL4A, позволяющий запускать в данной среде perl-программы, в частности веб-сервер, способный генерировать HTML страницы по запросам Perl. Как написать свой веб-сервер на Perl под Android можно ознакомиться здесь или скачать немного измененный под работу с PHL вариант здесь.
ссылка на оригинал статьи https://habrahabr.ru/post/304634/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *