?

Log in

Главная Друзья Календарь Инфа Мой сайт
Serz Minus
Проверка новых сервисов
Оставить комментарий

У всех пользователей ActiveState Perl возникает проблема, почему не выполняется строка вида:
#!/usr/bin/perl -w
вначале каждого скрипта CGI, запущенного под Apache. Некоторые советуют прописать команду поиска интерпретатора в файл C:/usr/bin/perl.bat – но это будет работать только тогда когда скрипт запускаем мы сами, а не web-server Apache! Так вот, чтобы можно было сделать нормальнозапускаемые скрипты под Apache опишу как это сделать буквально в 2-х шагах! Вы спросите – а зачем вообще использовать путь #!/usr/bin/perl –w а не, например, #!C:/server/Perl/bin/perl –w где установлен интерпретатор? – ответ прост! Если вы разрабатываете скрипты для серверов под unix/linux системы на Windows, то пользоваться системой контроля версий (а это неотъемлемый атрибут современных разработок OpenSource) у вас не получится вовсе! И еще – неужели Вам приятно постоянно править эту первую строку? Не легче ли ее оставить в покое?

Метки:

Оставить комментарий
Спустя месяц.
За этот месяц собственными силами удалось сделать невозможное – написать очередную версию собственного шаблонизатора. Стимулом написания новой версии послужили накопившиеся пожелания и требования к модулю. Удалось реализовать возможности:
  • модуль стал корректно работать с файлами кэша;
  • модуль стал быстро работать с большим объемом данных, что позволяет выгружать «здоровые» отчеты;
  • модуль разбит на компоненты, что, несомненно, упростило его поддержку;
  • модуль стал строже обрабатывать ошибки разработчиков, что позволяет видеть текст ошибки на уровне сервера, а не браузера;
  • интерфейс модуля стал более жесткий;
  • модуль теперь может нормально работать с mod_perl;
  • модуль стал корректно устанавливаться на версии Perl 5.10_00.
Все перечисленное выше не сделало модуль тяжелым, таким как проект Template Toolkit. У модуля вплоть до текущей версии сохранились все качества, которыми он был наделён и ранее. Более того, удалось добиться того, что от имени роботов-тестеров перестали поступать «жалобные» письма с темой «ошибка тестирования» или что-то в этом духе. На карту тестирования можно посмотреть здесь: http://bbbike.radzeit.de/~slaven/cpantestersmatrix.cgi?dist=TemplateM+2.22 или даже здесь, если интересуют детали: http://cpantesters.perl.org/show/TemplateM.html#TemplateM-2.22

Документация и исходники модуля доступны по ссылке: http://search.cpan.org/~abalama/TemplateM-2.22/

Теперь, после того как модуль написан, одобрен и размещен на CPAN, можно говорить о его использовании. Но для этого нужно какое-то время, и конечно же, участие пользователей (программистов на Perl под WEB). А мне, как разработчику, остается только ждать замечаний, предложений и просто мнения. С радостью приму все. Если Вы согласитесь мне помочь в этом несложном но серьезном деле, то я буду только рад. Заранее спасибо
модуль стал корректно работать с файлами кэша; 
2 комментария or Оставить комментарий

Что послужило поводом написания своего собственного шаблонизатора? Почему сразу не пользоваться стандартным, всем привычным щаблонизатором? – На эти вопросы точный ответ я дать не смогу, т.к. на сегодняшний день бытует мнение «я делаю как делают все».

В этом посте я попытаюсь сравнить несколько шаблонизаторов, в том числе и тот, который написан мной.
Итак. На повестке дня 4 избранных шаблонизатора (отсортировано по степени использования):

  1. Template::Toolkit
  2. HTML::Template
  3. CTPP
  4. TemplateM
  5. Без использования шаблонизатора

Сравнивать будем по простой задаче: «получить столбик значений от 1 до 10000».
Все модули будут работать на том же принципе, что и исходная задача «Без использования шаблонизатора»:

use Time::HiRes;
 
my $start = Time::HiRes::time;
 
print "Content-type: text/html\n\n";
print "Start time: 0<br>";
 
my $out = '';
foreach (1..10000) {
$out .= "$_<br>\n"
}
 
print "Finish time: ", Time::HiRes::time - $start;
print $out;
 

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

Start time: 0
Finish time: 0.015625

1
2
3
...
10000

Как видно, операция выполнилась за время – 16 тысячных секунды. Именно это число и будет говорить нам о производительности тестов.

Теперь попробуем выполнить код используя модуль CTPP в синтаксисе Template::Toolkit:

my $template = CTPP->new();
 
my $arr = [1..10000];
 
$template->process("./tt.html", { var1 => 'TT', var2 => $arr },\$out) || die $template->error();
 

Получим результат примерно равный:

Finish time: 0.19375

Теперь проделаем тоже самое с помощью Template::Toolkit без использования C модулей:

my $template = Template->new({RELATIVE=>1});
 
my $arr = [1..10000];
 
$template->process("./tt.html", { var1 => 'TT', var2 => $arr },\$out) || die $template->error();
 

Получим результат равный примерно:

Finish time: 0.71398

И тоже самое с использованием Template::Toolkit и C модули:

Finish time: 0.23020

Теперь пришла очередь мудуля HTML::Template. Он справился с этой же задачей за 0.4576 секуны.

И наконец модуль TemplateM. У этого модуля реализовано 2 концепции. Первая концепция подразумевает что шаблон будет наполянтся небольшим объемом данных, вторая же концепция подразумевает что шаблон будет наполняться большим объемом данных (Galore).

use TemplateM 2.20 'galore';
my $template = new TemplateM(-file=>'test.shtml', -cache => ".");
 
$template->stash(start => $start);
 
my $loop = $template->start('A');
foreach (1..10000) {
    $loop->loop({v=>$_});
}
$loop->finish;
 
$template->stash(finish => $finish);
 
print $template->html;
 

Этот шаблонизатор справился с задачей примерно за 0.2785 секунды.

Итак, подведем маленький итог. Самым быстрым стал шаблонизатор Template::Toolkit с включенными C сабмодулями. Но это ли является главным в работе шаблонизатора? На этот вопрос каждый сможет дать свой собственный ответ. Я лишь приведу таблицу статистики, которую может составить каждый работающий с набором шаблонизаторов.

  1. Template::Toolkit
  2. HTML::Template
  3. CTPP
  4. TemplateM
  5. Без использования шаблонизатора

Шаблонизатор
1
2
3
4
5
Скорость
0.230
0.458
0.194
0.279
0.016
Место по скорости
3
5
2
4
1
Широкие Возможности
+
-
+
-
-
Маленький размер модуля
-
+
-
+
+
Каскадные циклы и условия
+
-
+
+
-
Простота логики
-
+
-
+
+
Простота в использовании
+
+
+
+
-
Устойчивость к ошибкам
+
+
-
+
+
Удаленный доступ к шаблону
+
-
+
+
+
SSI директивы
+
-
+
+
-
Кэшировании
+
-
+
+
+
Многокаскадная обработка
+
-
+
+
+
Актуальность использования
+
+
+
+
-
Нет багов
-
+
-
-
+
Кроссплатформенность
+
+
+
+
+
Написано не только на Perl
-
-
+
-
+
Понятная документация
-
+
-
+
+

Пользуясь этими данными легко выбрать для себя подходящий шаблонизатор. Что касается "самописных" шаблонизаторов, типа TemplateM, то перед тем как их писать нужно чётко представлять целесообразность использования в контексте проекта. Например, TemplateM отлично подходит если:

  • В проекте были или используются файлы SSI (shtml);
  • В проекте используется удалённое и распределенное хранение элементов дизайна;
  • Проект пишется в средах: Komodo, Rapid CSS или Macromedia (Allaire) Homesite;
  • Нет возможности установить модули типа Template::Toolkit, CTPP или HTML::Template

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

Метки:

Оставить комментарий
В Perl 5.8.x появилась более-менее нормальная поддержка формата UTF-8. Более того, все больше и больше «припирает» необходимость делать все проекты не в своей родной кодировке типа Windows-1251 (CP-1251), а в универсальной кодировке формата UTF-8.
Начиная исследование более «мягкого» переезда с родной кодировки (Windows-1251) на кодировку формата UTF-8 мы сталкиваемся с необходимостью делать следующее:
  1. Сохранять все скрипты и библиотеки в кодировке формата UTF-8;
  2. В начало каждого скрипта или библиотеки писать:
    use utf8;
  3. Следить за флагом UTF-8 каждой скалярной переменной с которой придется работать как с набором СИМВОЛОВ кодировки формата UTF-8;
  4. Использовать самые последние версии модулей для Perl; особое внимание следует уделить модулям интерфейсов и шаблонизаторов, например модуль CGI;
  5. Работать с базами данных преимущественно в кодировке формата UTF-8.
Теперь подробнее про каждый пункт.
1 и 2. Чтобы работать с символами UTF-8 как СИМВОЛАМИ сами СИМВОЛЫ можно представлять как \x-последовательности или же как сами символы. Работать с \x-последовательностями мягко сказать - не «наглядно». Возьмем простой пример:
print "\x{00ab}\x{d0b1}\x{d0bb}\x{d0b0}-\x{d0b1}\x{d0bb}\x{d0b0}-
\x{d0b1}\x{d0bb}\x{d0b0}\x{00bb}";
и:
print "«бла-бла-бла»";
Как видно, второй вариант намного понятнее.
Для того чтобы можно было в теле кода употреблять чистые символы, а не коды, и служит прагма utf8. Более того, эта прагма позволяет писать непосредственно в коде комментарии и некоторые литеральные лексемы.
3. UTF-8 это не просто формат, это еще и подход к доступу данных! Это стоит помнить каждый раз, когда по ходу написания кода будет встречаться строковая обработка с участием символов формата UTF-8. Дело в том, что некоторые символы UTF-8 обрабатываются не как символы UTF-8, а как символы ASCII! Например:
use utf8;my $string = "«";
print $string, "\n"; # На выходе: «
$string =~ s/«/-/; # На выходе: ᦏ-
и:
use utf8;
my $string = "«";
utf8::_utf8_on($string); # Принудительная установка флага UTF-8
print $string, "\n"; # На выходе: «
$string =~ s/«/-/; # На выходе: -
Функция _utf8_on() устанавливает флаг UTF-8. Эта функция является тестовой и приведена для наглядности. Более правильный способ - такой:
use utf8;
use Encode;
my $string = "«";
Encode::_utf8_on($string); # Принудительная установка флага UTF-8
print $string, "\n"; # На выходе: «
$string =~ s/«/-/; # На выходе: -
Или еще лучше: 
use utf8;
use Encode;
my $string = "«";
Encode::decode_utf8($string); # Декодирование и установка флага UTF-8
print $string, "\n"; # На выходе: «
$string =~ s/«/-/; # На выходе: -
«Внутри» Perl каждый скаляр имеет «невидимый» флаг, состояние которого нужно контролировать каждый раз при установке и чтении значения этого скаляра. Для этого контроля существует группа функций пакета Encode:
_utf8_off, _utf8_on, is_utf8, utf8_downgrade, utf8_upgrade
В ближайшее время разработчики прагмы utf8 унаследуют эти функции. Первые попытки этого уже сделаны.
4. UTF-8 активно внедряется в Perl и его модули. Разработчики модулей активно начали изменять из реализацию руководствуясь новыми требованиями и стандартами. Для того, чтобы быть в ногу со временем нужно всегда контролировать те модули, которыми Вы будете пользоваться в своей работе и ярким представителем таковых является модуль CGI. Процедура param() модуля CGI 2.91 и младше не учитывали параметры в формате UTF-8, когда как новые учитывают, например:
if ($PARAM_UTF8) {
eval "require Encode; 1;" unless Encode->can('decode');
@result = map {ref $_ ? $_ : Encode::decode(utf8=>$_) } @result;
}
Таким образом совет: следите за свежестью модулей!
5. современные БД умеют работать с UTF-8, чтобы не «заморачиваться» с постоянными перекодировками, следует хранить, передавать и обрабатывать данные в БД в кодировке UTF-8! Если же стоит необходимость всё же конвертировать данные, то следует пользоваться функциями модуля Encode. В сети можно найти массу решений для конвертирования, но функции пакета Encode – самые надежные на сегодняшний день!

Метки:

Оставить комментарий
Решаем интересную задачу. В комплекте установленного на платформу Windows - ActiveState Perl 5.8 + mod_perl 2 + Apache 2.0 всё работает хорошо, но вот модуль CGI не обновляется с помощью стандартных средств и в упор не хочет работать с mod_perl 2 должным образом. 

Удалось установить причинное место. Причина кроется в том, что старый модуль CGI (до версии 3.0) не знал о существовании mod_perl2 и не принимал его во внимание вообще! Из-за этого все установленные регистры модуля CGI не очищались. Чтобы их очистить, пришлось написать заплатку. Её можно установить в стандартный модуль, а можно и в свой самописный код.  В самом первом хэндлере, который мы перехватываем, вставляем код:

if (CGI->VERSION() < 3.00) {
   if ($r->can("cleanup_register")) {
      $r->pool->cleanup_register(\&CGI::_reset_globals);
   } else {
      eval "use APR::Pool(); 1;";
      if (APR::Pool->can("cleanup_register")) {
           $r->pool->cleanup_register(\&CGI::_reset_globals);
      }
   }
}
После этого все регистры спокойно очищаются и мы продолжаем работать как ни в чем не бывало. Если наш системный администратор обновит модуль CGI на сервере,  то этот код автоматически отключится и не будет выполнять никаких действий.

Метки:

Оставить комментарий
Начну ленту про язык Perl.

Впрочем про сам язык здесь писать ничего не буду, а постораюсь описывать пути решения конкретных "трудностей" и задачь... Последнее время мне приходится иметь дело с такими вещами как совместимость различных модулей, например, mod_perl и CGI.pm. С вопросами совместимости рано или поздно сталкивается каждый разработчиик, в частности любой разработчик web-приложений на языке Perl.

Метки:

1 комментарий or Оставить комментарий