четверг, 26 ноября 2009 г.

Perl :: Структуры данных :: Переменная :: Объявление переменной

В арсенале Perl имеется достаточно широкий набор приёмов, которые могут использоваться разработчиком при создании переменных там, где это необходимо в данный момент; однако за это, как, впрочем, и за всё остальное в этой жизни, программисту приходится платить, а здесь начинается та часть, где надо быть особенно внимательным. Данный язык программирования, в самом деле, может облегчить существование разработчика за счёт правильного использования специальных помощников ‘my’, ‘local’, ‘our’. Каждый из них по-своему может быть полезен, и сберечь массу времени при отладке готовых программ, не говоря о том, что можно (и должно) использовать их "врождённые" свойства, которые не надо "программировать" самому, поскольку создатели языка об этом уже позаботились, а разработчику надо всего лишь уметь правильно ими пользоваться.

Главным в работе с переменными, равно как и со всеми другими имеющимися типами данных языка, является так называемая "область видимости" переменной. Существует несколько простых правил на сей счёт:
  • когда программа может использовать несколько одноимённых (но не равных по значению в каждый конкретный момент времени) переменных, в языке существует встроенный механизм "отслеживания" и использования переменных с одинаковыми именами и в разных областях видимости (или блоках), который реализован путём объявления переменной с помощью ‘our’; можно сказать, что в данном случае происходит автоматическое "переопределение" значений переменной по ходу всей программы;

  • когда же разработчику необходимо каждый раз в пределах какого-либо блока использовать переменную с одним и тем же именем, но с абсолютно "чистым" начальным значением, то, как правило, (и до возникновения ‘our’) используется ‘my’;

  • в случае же когда программист хочет очень жёстко "привязать" само существование конкретной переменной в пределах одного блока кода и напрочь "забыть" о том, что она когда-то существовала после выхода из него, у него всегда имеется ‘local’ для этого.
Подобно многим другим языкам программирования объявление переменной может происходить как с присваиванием ей начального значения, так и без оного, например: 'my $var=1;', где между переменной и её значением находится оператор присваивания (пожалуйста, не путайте его со знаком «тождественно равно» ‘==’). Существуют также иные способы присваивания значений переменным, но об этом не здесь и не сейчас.

Если читатель считает необходимым освежить свои знания по переменным, то раздел стандартной документации 'perldoc perlvar' всегда к Вашим услугам; или же зайдите на любое из зеркал CPAN.org, чтобы найти нужный Вам раздел документации.

пятница, 13 ноября 2009 г.

Perl :: Структуры данных :: Переменная :: Значение переменной

Во-первых, как всем наверное известно, для обозначения переменной в Perl используется знак доллара ‘$’. Согласно создателю этого языка он выбрал такое обозначение, так как оно очень похоже на латинскую букву ‘S’ и очень подходит для мнемонического обозначения слова ‘scalar’ (скаляр). С другой стороны, памятуя лингвистическое прошлое г-на Волла уместно предположить, что ‘S’ может относиться и к слову ‘single’ (один, единственный).

Это становится актуальным, когда надо запомнить, что в Perl скалярный контекст соотносят с переменной, то есть, скаляром. По большому счёту всё, что надо знать в данном языке (или почти всё) вращается вокруг контекста, что может стать камнем преткновения для любого программиста.

Ещё одно замечание в отношении имён переменных в Perl: не так давно и совсем не так как во многих других языках программирования стало возможным называть переменные практически на любом языке (речь не идёт о транслитерации): язык, который имеет письменность и представлен в наборе символов Юникода может принадлежать к Индо-Европейской, Сино-Тибетской, Романо-Германской или любой другой семье языков.

Переменная может выглядеть как ‘$var’ в традиционном представлении или же если есть необходимость представления имени переменной, скажем, на китайском, то это может быть нечто наподобие $輕 (qìng - лёгкий, легко).

FYI: (%perldoc) perldata - Perl data types

вторник, 27 октября 2009 г.

Perl :: Мифы и реальность с HTML::Mason

То, что знают все


Для людей, которые даже никогда сами не имели в своей программерской практике никакого опыта с Perl само слово HTML::Mason может быть не ново, а сам CPAN может вызывать равно как и зависть, так и восторг. Среди огромного количестве библиотечных модулей данного репозитория, HTML::Mason уже смог выдержать ряд релизов и квалифицироваться не иначе как профессиональная среда разработки веб-ресурсов. Впрочем, можно долго рассуждать на тему того, что именно представляет из себя это явление, но вот с чем приходилось сталкиваться чаще всего, когда произносилось слово “HTML::Mason”, так это что-то типа: «ну, так без mod_perl это никак!».

Никто и не скрывает, что данная библиотека и разрабатывалась с этим расширением веб-сервера Apache в голове; но далеко не все из библиотек, которые присутствуют на CPAN могут (хотя бы в части pod) «похвастаться» таким разнообразием возможных применений; здесь речь пойдёт о том, как «по одёжке – протягивать ножки», а точнее, как можно используя то, что доступно и под рукой, делать достаточно хорошие и надёжные вещи.

Наверное, найдётся далеко немного людей, которые могут с гордостью сказать, что вот там-то и там-то они использовали HTML::Mason в полном объёме не только без mod_perl, но и без Apache; многое как и это, о чём Вы, наверняка знаете, тоже возможно с данной библиотекой. Однако в данном случае будет немного иная задача, а именно, как используя практически весь арсенал HTML::Mason заставить его работать на обычном сервере, где есть лишь старый, добрый CGI.pm.

 

О чём, «молчит» г-н Рольский

 

Несмотря на то, что в комплекте HTML::Mason имеется хороший набор документации и масса примеров практически «на все случаи жизни», практика показывает, что то ли умышленно, то ли нет (и этому существует масса свидетельств в интернете, к сожалению) в отношении CGI имеется там явный пробел. Разумеется, что все, кто когда-либо пытался решить подобную проблему сразу же обращались к HTML::Mason, HTML::Mason::Admin, HTML::Mason::CGIHandler и прочим вещам. И, наверное, большинство из этих смельчаков либо останавливало выбор на чём-то другом, либо... вообщем, это не важно уже сейчас, поскольку это «большинство» приобрёв некоторый печальный опыт «работы» с HTML::Mason, возможно, уже никогда более не обращало свой взор сюда снова. А жаль! Авторы этих строк никоим образом не ставят всё это в упрёк команде разработчиков HTML::Mason, но, наверное, всё же стоило пролить свет на возможности HTML::Mason в этом направлении для массы несведущих.

Итак, что же согласно стандартной документации предлагает данная библиотека всем тем, у кого нет возможности пользоваться всеми прелестями mod_perl? Сразу надо сказать, что вариантов не очень много и все они, как правило, сводятся к двум.
Вариант использования HTML::Mason в отдельно взятом (и сделанном) cgi-скрипте с самого начала, даже если не вдаваться в подробности возможной сферы применения, сводит на нет всю мощь HTML::Mason в части многократного использования в разных местах приложения одних и тех же компонент; а для системных администраторов шаблоны не нужны и вовсе – возможностей Perl хватает с головой. Если кратко, то этот вариант заставляет почти попрощаться с системой шаблонов и, что самое обидное, с тем механизмом, посредством которого они могут взаимодействовать!

Вариант второй указывает на незавершённую эмуляцию взаимодействия HTML::Mason с Apache API в виде HTML::Mason::CGIHandler. По словам самих разработчиков это лишь «жалкое подобие» того, что возможно в связке с mod_perl. И это действительно так. Вопрос «а надо ли это вообще?» авторами данных строк даже никогда не ставился, а вот стоит ли начинать то, что не очень хочется заканчивать, пока остаётся открытым.

 

Что по чём и зачем это надо

 

История открытий и изобретений пестрит примерами, которые родились на стыке двух или более технологий, или просто понятий. HTML::Mason, в этом смысле, не является исключением, к счастью. Для тех, кто или знаком с историей Интернета, или просто интересовался ею, должна быть известна история возникновения протокола CGI; который до известного времени удовлетворял всем известным ранее требованиям динамического взаимодействия клиента и сервера. Времена меняются – люди тоже, а вместе с ними и их «игрушки».

Старая сказка про то, что веб-дизайнер никогда не сможет понять веб-разработчика начала, кажется, уже устаревать, когда мир увидел всякого рода системы управления контентом, системы шаблонов и иже с ними. Но всегда и везде первым (хотя, впрочем, и не обязательно первым) встаёт вопрос о платформе. Итак, если побродить по бескрайним просторам Интернета, то краеугольным вопросом, в нашем случае, по-прежнему остаётся наличие mod_perl у провайдера. Для тех, кто когда-либо занимался подобным «изысканием» должно быть известно, что хостинг подобного рода далеко не копеечный и встречается далеко не везде.

Причин тому достаточно, но главная – в якобы дорогостоящем сопровождении данного вида хостинга, с чем мы не можем согласится (и у нас также есть достаточно причин для этого). Поэтому, возвращаемся к тому что может найтись практически везде – к CGI.pm со стандартными примочками и что стоит действительно копейки. HTML::Mason, если не установлен, то получить его на обычном хостинге не есть проблема; все проблемы возникают после того, как окрылённый обладатель готового сайта, который собран согласно документации и вроде бы работает «в домашних» условиях, попытается привинтить его на своем хосте у провайдера.

Чтобы не томить души страждущих, сразу надо сказать, что отправной точкой является наличие cgi-handler, т.е. скрипта, который «пропускает» через себя все запросы проходящие через CGI окружение и перенаправляет их к HTML::Mason для дальнейшей работы. До сих пор вроде бы всё ясно; теперь несколько замечаний о святая-святых HTML::Mason, а именно об auto- и dhandler.

В общем и целом, их работа (равно как и содержимое) неизменны, но поскольку то, что в CGI называется %ENV, а в HTML::Mason - %ARGS (а оно не только называется, но и в самом деле суть две большие разницы) является универсальными контейнерами для обмена данными через переменные окружения (а, как известно mod_perl очень плотно трётся с Apache, а не с CGI, что и выросло у HTML::Mason), то неплохо было бы сказать HTML::Mason откуда их брать, не так ли?

 

Теория, которая витает в воздухе

 

В теории, или точнее в документации, говорится, что autohandler срабатывает прежде всего другого и всегда, а dhandler только в случае... ну, вообщем, это известно всем. Как оказывается на практике, в CGI окружении поведение этих рабочих лошадок HTML::Mason несколько иное. Оказывается, что в таких условиях dhandler, если всё оставить согласно документации, просто не срабатывает тогда, когда надо; хотя autohandler работает без проблем.

В чём же дело? Собака зарыта в том, как принудительно завести dhandler; это значит, каким образом «вкинуть» его в CGI. Несмотря на то, что данный пример такого проброса не претендует на звание идеального, но там, где не требуется обработка 1000 одновременных запросов, он справляется вполне достойно. Вот рецепт:

#!/usr/bin/perl
#Файл: mason_handler.cgi ( cgi handler для обработки компонент, auto-, dhandler’a )
use HTML::Mason::CGIHandler;
use lib '/path/to/lib ';  # Абсолютный путь к библиотекам Ваших модулей
use YourModule1;    # Ваш модуль1
use YourModule2;    # Ваш модуль2
use utf8;

# Установка для принудительного вызова dhandler
$ENV{PATH_INFO} = '/path/to/DocumentRoot/dhandler';

my $h = HTML::Mason::CGIHandler->new(
  data_dir   => '/path/to/mason data dir',
  comp_root => '/path/to/component/root',
  allow_globals => [qw($globalscalar)],
);

$h->handle_request;


Что ещё надо было бы сказать про HTML::Mason

 

Данный раздел помещён здесь далеко не случайно, а скорее как «крик души». Наверное, многие разработчики, которые имеют работы с неанглоязычными данными сталкивались с различного рода казусами ввода-вывода и последующего отображения языков, отличных от английского.
Начнём с классики, которая в данном случае представляется UTF-8. В теории (perlunicode, etc) говорится о встроенных классах символов типа “\p{InBasinLatin}”, “\p{InCyrillic}” и так далее, которые в связке с оператором ‘qr()’ могут, и действительно делают, чудеса. Также нелишним будет вспомнить и старушку ‘quotemeta()’, которая и сейчас бывает полезной; однако, когда дело доходит до использования всего этого добра в HTML::Mason, то всё оказывается не так гладко.

Приведём пример: у вас есть таблица mysql, которую вы используюте исключительно с ‘SET NAMES utf8’ (ну, чтобы попроще было со смешанными текстами и сборными страницами) и которая также сама имеет там, где надо ‘CHARSET=utf8 COLLATE=utf8_unicode_ci’; затем, вам где-то в форме у пользователя надо бы «почистить» ввод с помощью всеми любимой ‘s///go’ (само собой разумеется, что у вас все страницы содержат валидный XHTML с мета-тэгом ‘charset=utf-8’, указанным явно или через ‘headers_out()’ от HTML::Mason), но почему-то «очистка» не работает как надо! Вы лихорадочно пытаетесь задействовать, опять же согласно стандартной документации Perl, до боли знакомую прагму ‘utf8’ прямо в компоненте... теперь с регулярными выражениями всё, кажется, в порядке, но при этом как-то странно выглядит контент на сборной странице. Вот вроде бы появился свет в конце туннеля, вы «находите» спасительный модуль Encode с его “decode(), encode()” и пытаетесь «нормализовать» входные данные, поступающие прямо из формы... Результат тот же, и не тот, что надо.

Возможно, ваша собственная история несколько иная, но мораль сей байки такова: все данные, которые соответствуют UTF8, во внутреннем представлении Perl практически всегда отличаются от приходящих из интерфейса; единственное назначение такой формы данных, хотя справедливости ради надо сказать, что они вполне пригодны для отображения в браузере, это скармливание их регулярным выражениям, которые, в свою очередь, если составлены верно, с радостью их обработают в таком виде и выдадут вам правильный (читай – ожидаемый) результат. Во всех же остальных местах вашего драгоценного ресурса их никогда нельзя выпускать «на волю», в противном случае, будет беда: явное включение UTF8 каким-либо образом хотя бы в одной из компонент HTML::Mason приводит к тому, что данные из этой компоненты отображаются правильно, а все остальные, как в нашем случае со сборной страницей, будет «не так».

Проблема обрела форму, но где же решение? Здесь также нелишне вернуться к первоисточникам: там настоятельно советуют следовать старому принципу – «разделяй и властвуй», что в применении к настоящей проблеме можно перефразировать следующим образом. Все процедуры, которые требуют сугубо юникодовской трактовки данных при обработке исключительно средствами языка Perl, должны находиться только в модулях, а не в компонентах; там же можно использовать инструменты, подобные Encode::encoded/decoded(“uf8”, $datum). Это одно из, слава нашему Богу, немногих ограничений при планировании приложений, разрабатываемых с помощью HTML::Mason.

Это всё было «внутри», теперь же несколько слов про то, что возможно сделать «снаружи». В HTML::Mason имеются встроенные *escape* функции; не стоит, наверное, цитировать авторов, надо лишь сделать несколько замечаний относительно вещей, подобных ‘|h’.
На самом деле, если у Вас англоязычный ресурс, то повода для беспокойств нет. Однако в противном случае, если Вы используете кодировку unicode (utf8), следующий код поможет решить проблему с организацией литерального представления данных пользователя. Это нужно, например, тогда, когда на Вашем ресурсе пользователи осуществляют ввод посредством html form. Если пользователи введут данные вместе с HTML – тэгами, тогда при отображении этих данных, чтобы не нарушился интерфейс ресурса нелишним будет следующее:

Файл: autohandler
……
% $m->interp->set_escape( h => \&HTML::Mason::Escapes::basic_html_escape );
% $m->call_next();
……

Файл: <Ваша компонента>
……
<% $htmlstring | h %>
……

Пример сборки ресурса

 

Здесь мы хотели бы проиллюстрировать на простом примере всё, о чём было сказано выше.
В данном примере мы создаём небольшой ресурс, составными частями которого будут:
  • модуль, основным назначением которого будет сопряжение с БД;
  • autohandler и dhandler
  • набор компонент для сборки нехитрого интерфейса.
Замечания и комментарии будут даваться по ходу представления исходного кода ресурса.
Пример приложения можно скачать здесь (~ 10 Kb).

пятница, 23 октября 2009 г.

Perl :: Юникод и регулярные выражения

   Перефразируя известного французского мыслителя применительно к Perl вполне справедливо заметить: «Если бы не существовало регулярных выражений, то не было бы и языка Perl». Возможно, Лари Уолл и не согласился бы с данным утверждением, но никто, наверное, не осмелился бы оспаривать важность регулярных выражений для приверженцев этого языка (обратное, вероятней всего, также верно). Как бы там ни было, но, согласитесь, тяжело найти Perl программиста, который бы не использовал регулярных выражений (а иначе, он попросту не использует его).

   Существует множество ресурсов по регулярным выражениям, но неоспоримым лидером, конечно же, является 'Mastering Regular Expressions' Дж. Фридла, которую стоит прочитать, с которой стоит не соглашаться и, в конце концов, по которой стоит учиться. Ряд вопросов, которые здесь будут затронуты, касаются в определённой степени самого Юникода, как явления необычайно важного, и то, как регулярные выражения в Perl могут помочь в их решении.

   FYI: perldoc perlunicode - Perl Unicode support

   Чтобы быть достаточно подготовленным для прочтения данного материала читатель должен уверенно себя чувствовать в вопросах работы регулярных выражений и особенно в части, которая касается построения объектов регулярных выражений; а также, как внедрять исполняемый код в регулярные выражения в ходе замены или при поиске совпадений, чтобы динамически выполнять куски кода внутри m// или s///. Было бы неплохо, если бы читатель уже имел некоторый опыт работы с Юникодом и знал его организацию, и что при использовании всех вышеупомянутых предметов необходимо использовать 'use utf8' либо 'use encoding "utf8"' вместе с ещё одной прагмой - 'use re "eval"', которая разрешает внедрять исполняемый код в регулярные выражения. Всё это, естественно, само собой подразумевает, что читатель знаком с поведением '\w' в среде Юникода.

   И последнее перед тем, как приступить к повествованию: 'use locale' накладывает гранитную глыбу на кросс-платформенность ваших приложений, в особенности, когда у вас присутствует что-то типа '\p{InCyrillic}' или 'p{InCJKCompatibilityIdeographs}', поскольку эти «звери» становятся чрезвычайно чувствительны к настройкам системы в регулярных выражениях и в контекстах 'use bytes' и 'no bytes'.

   FYI: perldoc utf8 - Perl pragma to enable/disable UTF-8 (or UTF-EBCDIC) in source code

   Чтобы покончить с введением, давайте освежим в памяти несколько базовых функций, которые могут помочь в наполнении вакуума о Юникоде:

#!/usr/bin/perl
use strict;
use encoding 'utf8';
our ( @packed, );
@packed = map{chr($_)} (0x4E00 .. 0x9FFF);
print $_, "\n" for @packed[0 .. 9];
exit(0);


этот малыш может сгенерировать практически мгновенно более 20.000 иероглифов, которые используются в китайском, японском, корейском и, возможно, в старо-вьетнамском языках. Строка:

@packed = map{chr($_)} (0x4E00 .. 0x9FFF);


может быть совсем безболезненно переписана как:

@packed = map{pack 'U', $_} (0x4E00 .. 0x9FFF);


   Здесь функции 'pack' и 'chr' несомненно взаимозаменяемы.

   Теперь попробуем сделать что-либо более полезное. Поскольку Perl сам имеет встроенную поддержку Юникода нам не понадобится даже создание временных переменных и мы сможем сразу перейти к созданию нужных нам объектов регулярных выражений. Если у кого-либо из читателей возникнет вопрос по поводу присутствия китайских предложений, то можно ответить, что это потому, что постольку данный язык (а точнее CJK) имеет наибольшее присутствие в Юникоде в виде символов:

#!/usr/bin/perl
use strict;
use utf8;
use encoding 'utf8';
our ( $re, $sample );
$re = qr{(
        [\p{InCJKUnifiedIdeographs}] |
        [\p{InCJKCompatibility}] |
        [\p{InCJKCompatibilityForms}] |
        [\p{InCJKRadicalsSupplement}] |
        [\p{InCJKCompatibilityIdeographsSupplement}] |
        [\p{InCJKUnifiedIdeographsExtensionA}] |
        [\p{InCJKCompatibilityIdeographs}] |
        [\p{InCJKUnifiedIdeographsExtensionB}])}ox;

$sample = '五行: 一曰水, 二曰火, 三曰木, 四曰金, 五曰土 
  пять стихий: первая называется вода, 
  вторая — огонь, третья — дерево, 
  четвёртая — металл, пятая — земля 
  Five Elements: first is Water, second is Fire, 
  third is Wood, fourth is Metal, fifth is Earth';

while($sample =~ m/$re/g)
{
    print $1,"\n";
}
exit(0);


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

   Для тех, кому не понятно присутствие латинского «быка» в конце объекта регулярного выражения, мы рекомендуем обратиться к 'perldoc perlre'; ну, а для тех «книжных червей», которые желают знать всё обо всём, имеется несколько вопросов:
(1) откуда берётся значение для '$1'?
(2) в чём разница между 'use utf8' и 'use encoding "utf8"'? (то есть, точнее, почему они обе здесь?)
(3) почему модификаторы 'ox' и 'g' здесь разделены? Если у Вас готовы ответы на все эти вопросы, мы все как один снимаем перед Вами шляпы!

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

#!/usr/bin/perl
use strict;
use utf8;
use encoding 'utf8';
use re 'eval';
our ( $re, $index, $num, $line, $key1, $key2, 
  @estimate, @over, @under, %got, );

$re = qr{(
        [\p{InCJKUnifiedIdeographs}] |
        [\p{InCJKCompatibility}] |
        [\p{InCJKCompatibilityForms}] |
        [\p{InCJKRadicalsSupplement}] |
        [\p{InCJKCompatibilityIdeographsSupplement}] |
        [\p{InCJKUnifiedIdeographsExtensionA}] |
        [\p{InCJKCompatibilityIdeographs}] |
        [\p{InCJKUnifiedIdeographsExtensionB}])}ox;

@over       = qw(估計過高 переоценивать overestimate);
@under      = qw(估計過低 недооценивать underestimate);
@estimate   = (@over, @under);
$index = $num = 0;
grep{
        $num++;
        ($line) = $_;
        $got{$num}{s/$re/$index++/e} = $line if(/$re/);
    } @estimate;
foreach $key1 ( sort {$a <=> $b} keys %got )
{
    print "\n\nelement number:\t", $key1, "\n";
    foreach $key2 ( sort {$a <=> $b} keys %{ $got{ $key1 } } )
    {
                print "match number: \t", $key2, "\t",  
                $got{ $key1 }{ $key2 }, "\n";
    }
}
exit(0);


в скрипте присутствует определённая избыточность, но это исключительно в образовательных целях и, к тому же, в данном случае это никоим образом не влияет на КПД: попробуйте изобразить что-то типа этого, используя if/else управляющие структуры и сравните время выполнения. Что особенного в этих сорока строках? Есть пару вещей, которые заслуживают внимания:

(1)использование 'our'; как вы уже заметили, даёт возможность не передавать и не принимать никаких данных: всё решается за счёт создания хэша '%got', который программа вызывает и использует там, где надо;

(2)имеется инкремент счётчика '$index' по условию, который и возвращает номера элементов, отвечающих условию совпадения.

   Другим способом подобного мышления является использование внедрённого кода; несмотря на то, что это выглядит примерно так, как и выше, но это не только иной вариант применения регулярных выражений, а иной способ построения условий, которые внедряются в них:

#!/usr/bin/perl
use strict;
use utf8;
use encoding 'utf8';
use re 'eval';
our ( $re, $index, $num, $sample1, $sample2, 
   $sample3, %src, %got, );

$re = qr{(
        [\p{InCJKUnifiedIdeographs}] |
        [\p{InCJKCompatibility}] |
        [\p{InCJKCompatibilityForms}] |
        [\p{InCJKRadicalsSupplement}] |
        [\p{InCJKCompatibilityIdeographsSupplement}] |
        [\p{InCJKUnifiedIdeographsExtensionA}] |
        [\p{InCJKCompatibilityIdeographs}] |
        [\p{InCJKUnifiedIdeographsExtensionB}])}ox;

$sample1    = q[一萬一千一百一十一 11111];
$sample2    = q[天一地二天三地四 
  небу соответствует число один, 
  земле — два, небу— три, 
  земле — четыре... (и т. д.; «Ицзин») 
  one belongs to the Heaven, 
  two belongs to the Earth, 
  three belongs to the Heaven, 
  four belongs to the Earth... (etc, "YiJing")];
$sample3    =q[道生一, 一生二, 二生三, 三生萬物 
  Дао рождает одно (нерасчленённое единство), 
  одно рождает два (раздвоенность), 
  два рождает три (триаду), 
  от трёх рождаются все существа (вещи) 
  Dao bears one (indivisible unity), 
  one gives birth to the two (duality), 
  two produces three (triad), 
  those three flood everything (all things in the world)];

grep{ $src{$index++} = $_} ($sample1, $sample2, $sample3);

grep{
    grep{
            m#($re) ? (??{$got{$_}++ if($1 ne '')})#cgx;
        } split //, $src{$_};
    } sort keys %src;

foreach $num ( keys %got )
{
         print 'the match: ', "\t", $num, ' was seen:', "\t",  
              $got{ $num }, " time(s)\n";
}
exit(0);


   Построение хэша '%src' является несколько искусственным здесь, если сравнивать с мощью хэшей вообще, и в этом примере как нельзя лучше показан способ применения хэшей, точнее, «прозрачность» их использования через всю программу. Другой интересной точкой является функция 'split', которая действительно полностью «понимает» Юникод. Есть и другие функции с подобным поведением в Юникодовской среде, например: cho(m)p; но надо помнить, что не всё гладко в этом отношении. Чтобы понять это попробуйте поиграть с 'use/no bytes' и 'length'.

Всем привет! Команда Unencoded возвращается!

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



   Несмотря на тот факт, что в наши дни рост числа и качественное развитие прочих языков, таких как C, Ruby, .Net, C#, Java и PHP, Perl остаётся наилучшим выбором, когда, например, дело доходит до использования регулярных выражений или написанию на скорую руку мини-программ в одну строку. Все эти разнородные задачи никоим образом не умаляют его прочих достоинств и роли рабочего Верблюда, (данное замечание не имеет ничего общего с зарегистрированной торговой маркой JT Intl.) у которого, как всем известно, выносливости больше, чем у самой хорошей рабочей лошадки.

   Пусть посетителей не смущают такие заголовки тем, как «Переменная» или «Массивы» потому, что в повседневной жизни каждый, кто занимается программированием серьёзно, а не от случаю к случаю, сталкивается с проблемами, решение которых большей частью зависит от хорошего понимания основ языка программирования, его базовых структур и понятий; и о которых он уже, возможно, читал в учебниках для начинающих. Достаточно сказать, что решение многих «нерешаемых» проблем часто и густо находится в правильном и обоснованном использовании самых простых «кирпичиков» языка. Наверное, не надо говорить о том, насколько хорошо встроенные типы данных любого языка оптимизированы для конкретных задач, а в целом хочется напомнить, что «всё гениальное – просто».

   Надо заметить, что всё содержимое данного сайта это не бездумное копирование или конспектирование огромного объёма информации по какому-либо языку, доступное для любого человека, пожелавшего использовать тот или иной язык программирования; а оно (содержимое) суть личного опыта, хотя и существует определённая логика в последовательности изложения в целом. Авторы данного сайта действительно увлечены Perl и надеются, что рано или поздно также будут способны внести достойную лепту в сокровищницу Сообщества Открытого Кода.

FYI: (%perldoc) perl – Practical Extraction and Report Language