Понедельник, 8-е февраля

On Perl — блог о языке программирования Perl и его сообществе: Template::Semantic

Один из бешеных японцев™ — Наоки Томита — сегодня опубликовал на спане интересный модуль Tempalte::Semantic, один из немногих yet another-шаблонизаторов, на который стоит обратить внимание.

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

Например, чтобы вывести заголовок на страницу, сначала создаем HTML-заготовку:

<html>
    <head>
        <title></title>
    </head>
</html>

А затем описываем правила а-ля CSS:

use v5.10;
use strict;
use Template::Semantic;

say Template::Semantic->process(
    'title.html',
    {
        'html title' => 'My Title',
    }
);

Эта программа напечатает HTML-код с подставленным заголовком:

<html>
    <head>
        <title>My Title</title>
    </head>
</html>

Fantastique!

Описания с CSS-селекторами или XPath-адресами допустимо создавать и более сложной структуры, в том числе с вложенными хешами и списками (последние позволяют размножать фрагменты HTML-шаблонов).

Примеры наглядно описаны в документации модуля, а кроме того собраны в отдельном файле Template::Semantice::Cookbook.

/var/log/dev.log: Perl: Автоматическая печать PDF-документа при открытии [rus]

Поднялся вопрос: «Как добавить авто-старт печати при открытии файла PDF? Сделать всё в Perl»

Это «телодвижение» было нужно для минимизации кол-ва действий, которые должен выполнить пользователь, чтобы увидеть отчёт из системы на бумаге :)

Как и всегда, немного погуглив, я отыскал вполне себе такой хороший модуль на search.cpan.org :) Называется он — PDF::Reuse. Модуль позволяет совершать не малое кол-во манипуляций с готовыми PDF-файлами (подробнее...)

Что ж, модуль очень даже подошёл для моих нужд. Т.к. PDF может содержать JavaScript код, и диалог печати довольно просто из него вызывается, то его и решил использовать, а PDF::Reuse, по счастливой случайности, позволяет добавлять в PDF тот самый JavaScript код :)

Получить нужный результат можно следующим способом

#!/usr/bin/perl

use strict; use PDF::Reuse; use CGI qw/param/;

my $path = '/tmp/test/'; # путь до исходного PDF-файла

print "Content-type: text/html;charset=utf-8\n\n";

system('rm -f '.$path.'test1.pdf') if (-e $path.'test1.pdf'); # удаляем старый результат if (param('test') eq '1') { prFile($path.'test1.pdf'); # открываем файл prText(10,300,'Hello,'); # добавляем произвольный текст prText(30,340,'WORLD!!!'); # в файл prJs('function prn() { this.print(); } prn();'); # добавляем JS-код, который будет вызывать диалог печати prEnd(); # pfкрываем PDF print "<script>window.open('http://www.sdenix.net/test/test1.pdf')</script>"; } print "<html><head><title>PDF test</title></head><body>\n"; print "<form action='/test_pdf'><input type='hidden' name='test' value='1' /><input type='submit' value='Смотрим пример с авто-печатью' /></form><br />\n\n"; print "</body></html>";

Вот, собственно, и всё! Посмотреть живой пример можно тут. Теперь включаем фантазию и используем этот модуль в своих целях :)

Воскресенье, 7-е февраля

Perl — Говнокод.ру: Perl / Говнокод #2562

это работает на mySQL/PERL. да зачем нам реляционная база, мы сами можем манипулировать отношениями. comments_ptr это BLOB, c упакованным в него массивом int32 id'шников из comments.id хотя и есть comments.post_id <=> posts.id просто праздник какой-то! # куски кода выдернуты # смотрите внимательно на SQL #--- INSERT ------ my $comment_id = $ej->{dbh}->insert('blog.comments', ( 'id::primary' => '', 'post_id::numeric' => $param_id, 'user_id::numeric' => $ej->{user}{id}, 'text' => $newmess, 'time::numeric' => $ej->{time}, 'rating_ball::numeric' => $rating_ball )); my $_rating_ball = 0 + $ej->Query ('SELECT SUM(rating_ball) FROM blog.comments WHERE post_id = '.$param_id)->FetchRow; $ej->Query( 'UPDATE blog.posts SET update_time = '.$ej->{time}.', rating_ball = '.$_rating_ball.', '. 'comments_ptr = CONCAT('.Q(pack('L', $comment_id)).', comments_ptr) WHERE id = '.$param_id ); #--- DELETE --- $ej->Query('DELETE FROM blog.comments WHERE id = '.$comment_id); my $comments_ptr = pack('L*', $ej->Query('SELECT id FROM blog.comments WHERE post_id = '.$post_id.' ORDER BY time DESC')->FetchCol); my $_rating_ball = 0 + $ej->Query ('SELECT SUM(rating_ball) FROM blog.comments WHERE post_id = '.$post_id)->FetchRow; $ej->Query('UPDATE blog.posts SET comments_ptr = '.Q($comments_ptr).', rating_ball = '.$_rating_ball.' WHERE id = '.$post_id); #--- SELECT ---- my %q = $ej->Query('SELECT user_id, topic_id, name, text, SUBSTRING(comments_ptr, '.(1+($page-1)*40).',40) AS ptr, round(length(comments_ptr) / 4) AS cnt, create_time, pics_ptr, rating_ball FROM blog.posts WHERE id = '.$param_id)->FetchHash; my @id = (); my @user_id = (); my @text = (); my @time = (); if ($q{ptr} ne '') { my $r = $ej->Query('SELECT id, user_id, text, time FROM blog.comments WHERE id IN ('.join(',',unpack('L*', $q{ptr})).') ORDER BY time DESC'); @id = $r->FetchCol; @user_id = $r->FetchCol(1); @text = $r->FetchCol(2); @time = $r->FetchCol(3); } # потом еще вывод через Ж

Суббота, 6-е февраля

koorchik's Perl blog: ASCII Таблицы

Задача отправлять табличную информацию на почту.  И решение в общем то очевидное - использовать псевдографику(хотя возможно кого-то устроит html), либо просто выравнивать текст при помощи printf, но эффект уже не тот :).  Полчаса моего поиска в CPAN увенчались успехом и был найдет модуль Text::SimpleTable, который был предельно простым и полностью решал поставленную задачу. 

Пример:
use Text::SimpleTable;
my $t = Text::SimpleTable->new([5, 'Foo'], [10, 'Bar']);
$t->row('foobarbaz', 'yadayadayada');
$t->hr;
$t->row('barbarbarbarbar', 'yada');
print $t->draw;


.-------+------------.
| Foo   | Bar        |
+-------+------------+
| foob- | yadayaday- |
| arbaz | ada        |
+-------+------------+
| barb- | yada       |
| arba- |            |
| rbar- |            |
| bar   |            |
'-------+------------'

Пятница, 5-е февраля

Сообщество ru_perl в LiveJournal: Perl vs Ms Access

Може ктото практиковал?...

Подскажите плз чем можно и чем лучше разгрести базы Ms Access,
а также адресные книги Ms Outlook (&& || express), TheBAT.

On Perl — блог о языке программирования Perl и его сообществе: Why Perl?

На этой неделе в рассылке Moscow.pm я задал простой вопрос: как показать начинающим программистам сильные стороны Perl?

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

Stay tuned, епта.

Андрей Костенко: Ещё два события, в которых поучавствовали мои кривые ручки

Вышла новая версия DBIx::Class::Schema::Loader с множеством изменений. Одно из этих изменений – генерация POD-документации для автоматически созданных классов. Пользователи PostgreSQL получат ещё одну вкусняшку – все комментарии к их таблицам и столбцам автоматически переедут в документацию. Не буду показывать на автора этого патча пальцем, так как это неприлично.

И второе. Test::Pod::Coverage::Permissive. Принцип работы такой же, как и у Test::Pod::Coverage, только тесты валятся лишь в том случае, если появилась ещё одна не­за­до­ку­мен­ти­ро­ван­ная фунция.
Т.е. при первом запуске у вас тесты пройдут в любом случае. Задокументируете функцию — тесты пройдут. Напишете ещё одну незадокументированную функцию — обвалятся.

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

К чему это я — пользуйтесь и пишите баги.

Сообщество ru_perl в LiveJournal: ru_perl @ 2010-02-05T15:47:00

Почему не работает эта рекурсия (обход по FTP)?

sub ftpBrowse
{
        foreach ($ftp->ls)
        {
                next if ($_ eq "." || $_ eq "..");
                if ($ftp->mdtm($_))
                {
                        fileHandle($_);
                }
                else
                {
                        $ftp->cwd($_);
                        ftpBrowse;
                }
        }
        $ftp->cdup;
}

Ворота в Perl: Why Perl?

Лучший ответ в moscow.pm:

Я считаю, что те кто переходит с перла на пайтон/руби - еретики и скорее всего попадут в ад.

Why Perl?

Сообщество ru_perl в LiveJournal: По следам "Why Perl?"

Я не успел выссказаться в удаленном топике Валерия Студенникова "Why Perl?", но считаю необходимым сообщить одурманенным студентам СГАУ, что лет эдак через пять за Perl будут платить исключительно в рублях, рупиях и юанях. Поэтому начинающим программистам навряд ли стоит тратить свое время и силы впустую. Совмещать приятное с зарабатыванием денег не получится. Сейчас за тоннами священного говнокода стоит целая армия старперов предпенсионного возраста, которых меньше всего на свете интересует волшебный мир Java и XML. А это, по-моему, и есть та самая стезя, которую следует осваивать сегодняшним студентам.

Четверг, 4-е февраля

On Perl — блог о языке программирования Perl и его сообществе: Gearman (6) — рекурсивные воркеры

В фильме «13-й этаж» описывалась ситуация, когда смоделированный в компьютере мир создал свой собственный искусственный мир. При работе с Gearman можно столкнуться с задачами, которые в свою очередь удобно разбивать на части и отдавать на обработку следующим воркерам. Причем передача возможна в том числе тому же методу воркера, из которого она инициирована.

Вот пример. У нас есть сервис, отыскивающий по названию город в базе данных. Атомарная работа — поиск города — задача, вынесенная в отдельный воркер. При этом воркер умеет самостоятельно обрабатывать запрос, состоящий из нескольких слов:

my @words = $request =~ m{(\w+)}g;
for my $word (@words) {
    place_locality_search_word($word, $response);
}

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

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

На картинке — тестовый результат работы такого рекурсивного механизма для запроса со списком городов с ближайшими Perl-мероприятиями (софия екатеринбург амстердам москва киев vlorë).

P. S. Пока не стал коммитить такое решение :-)

Среда, 3-е февраля

On Perl — блог о языке программирования Perl и его сообществе: Geo::Ellipsoid

Из записной книжки программиста.

Январь

Я, конечно, знал, что Земля не идеальный шар, что он как-то приплюснут и называется то ли эллипсоидом, то ли геоидом, то ли еще как-то. Из университетских лекций в памяти держится название сферы вращения, ну да, ну и что дальше-то. Надо было посчитать расстояние между двумя точками на Земле, и пытаться восстановить в памяти весь курс трехмерной геометрии, да еще сделать поправки на неидеальность шара, — задача, конечно, интересная, но такой подход был бы совсем непрактичным. Хочется же и получить быстро результат, и порадоваться, и закрыть задачу.

Когда Яндекс открывал свои «Самолетики», они ввернули в заметке в их корпоративном блоге какое-то умное слово — ортодромии. Ну явно для того, чтобы поумничать. Кто же не знает, что ортодромия — это не про нашу Землю, это лишь кратчайший путь на поверхности сферы вращения. Мне-то нужно найти конкретный модуль по употребимому английскому названию и именно для Земли. Это название — great circle. Ищем.

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

Февраль

Стало скучно, что мы тут уже месяц считаем расстояние по ровненькому шару, а Украина до сих пор не выбрала президента. Что же там есть на спане еще? Йоу! Есть модуль Geo::Ellipsoid, и в нем с десяток разных формул, по которым описывают форму Земли. Хочу.

Так, что нужно? Интерфейс странноват, но понятен. Попробую на старом примере, посчитаю расстояние от Москвы до Киева. Как хорошо, что в папке /test у меня все это сохранилось, не надо заново искать координаты.

use v5.10;
use strict;
use Geo::Ellipsoid;

my @moscow = (55.7522, 37.6156);
my @kiev = (50.4333, 30.5167);

my $geo = new Geo::Ellipsoid(
    ellipsoid => 'WGS84',
    units => 'degrees',
    distance_units => 'kilometers'
);

my $dist = $geo->range(
    $moscow[0], $moscow[1], $kiev[0], $kiev[1]
);
say $dist;

В очередной раз напрягся, восстанавливая в памяти, что из longitude и latitude широта, а что — долгота, но вроде не перепутал и получил ответ, поохожий на правду. С GIS::Distance было 757 километров, с Geo::Ellipsoid — 759. (А оно должно было стать больше или меньше? Хотя какая разница, если все равно города на разной высоте относительно моря.)

Закоммичу, пожалуй.

Три минуты спустя

Коллега, прочитавший пришедший в почту дифф коммита, пишет: «Хм, а GIS:Distance::Formula::GeoEllipsoid?». Что это? Позырю. Блядь, я же забыл, что GIS::Distance может еще считать и по эллипсоиду. Читал же, когда его пробовал в прошлый раз. GIS::Distance это обертка, которая делегирует все расчеты другим модулям. Вместо того, чтобы приделывать новый модуль, можно было бы просто указать параметр ellipsoid => 'WGS84' к существующему. Незадача какая, сраный спан без аннотированных перекрестных ссылок.

koorchik's Perl blog: GUI в Perl: Frozen Bubble

Есть игрушка, которая мне очень нравится - FrozenBubble  и я давно в нее играюсь.  И я был приятно удивлен когда узнал, что она написана на Perl и SDL :)
Красочная игра, 100 уровней для одного игрока, есть поддержка сетевой игры, классный саундтрек.  Показательный пример создания качественной игры на Perl.




Сообщество ru_perl в LiveJournal: Перекодировка из utf-8 в utf-8

Всем день добрый,
Есть некий файл, который содержит русские буквы, и такое чувство что там utf-8 два раза перекодировали.

Ни как не соображу как все это раскодировать средствами perl.
Update - проблема решена, всем большое спасибо

Файл utf.bin который содержит: "Издатель", (Что должно раскодироваться как "Издатель") в бинарном виде это:

0000000 c3 90 cb 9c c3 90 c2 b7 c3 90 c2 b4 c3 90 c2 b0
0000020 c3 91 e2 80 9a c3 90 c2 b5 c3 90 c2 bb c3 91 c5
0000040 92 0a

Стандартная методика:
#!/usr/bin/perl -w --
use strict;
use utf8;
use encoding 'utf8', STDIN => undef;
use Encode;

while( <> ) { print decode("utf-8", $_); }


Не прокатывает.

Laziness, Impatience and Hubris: Всякая всячина и книги

Пора заканчивать заниматься ерундой и писать всякую фигню o Perl - блог закрыт. Сажусь за написание двух книг.

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

Вторая - "Распределенное программирование на Perl для домохозяек".
Эта книга предназначена для тех, кто любому кухонному комбайну предпочитает набор хороших кухонных ножей.

Логичней было начать с первой, но вторая сейчас интересней, поэтому есть большая вероятность, что первая будет лишь брошюркой.

Здесь будет опубликованы анонсы. До встречи.

Сообщество ru_perl в LiveJournal: Еще одна вакансия Perl-программиста

На постоянную работу в московскую компанию, занимающуюся недвижимостью требуется Perl-программист для разработки и ведения системы недвижимости.

Город: Москва
Район: ст.м. Преображенская площадь
Зарплата: до 60 т.р.
Рабочий день: с 10 до 19
Испытательный срок: 3 месяца

Требования:
Знание Perl, HTML, CSS, SQL (Postgres), общие зания по системному администрированию
Плюсом будет знание jquery
Умение работать с чужим кодом.

Работа по началу в команде, в будущем самостоятельная.

Если предложение вас заинтересовало, высылайте резюме на почту monterealty@gmail.com

Регулярные выражения на ya.ru: Время

Регулярное выражение для поиска значений времени — в 24-часовом формате или в буржуйском формате с записью «am/pm». Удобно для разбора логов.Ищется значение вида «часы:минуты» или «часы:минуты:секунды», разделитель полей — двоеточие. Перед «am/pm» не более одного пробела или вообще ничего./(?:0?[1-9]|1[012])(?::[0-5]\d){1,2} ?[AP]M|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2}/iПример:09:15099:15 AM12:40:36pm25:0212:7820.0920:09:7510:51:06vestibulum ante ipsum primis 11:24:35 in faucibusorci luctus et10:27 amultrices posuere cubilia127.0.0.1 - - [02 Feb 2010 17:40:15 +0200] "GET /index.htm HTTP/1.1" 404 214

Регулярные выражения на ya.ru: Про закрома of Rodina

Принято решение некоторые полезные регэкспы собрать в удобную кучку. Кучка будет потагана словом «закрома».Их будет не так много: регулярных выражений, которые, с одной стороны, нетривиальны, с другой — встречаются в жизни чаще одного раза, вряд ли найдется больше десятка.Требования просты: выражения должны матчить то, что надо, и не матчить то, что не надо :)Синтаксис по умолчанию — перловый (ну или PCRE, что почти одно и то же). Запись в синтаксисе POSIX — только если есть большая потребность.Обновлять регэксп в закромах будем, если в нём обнаружена ошибка или найден более эффективный (по времени выполнения). Вариант, менее эффективный, но более наглядный можно указать рядом. Прежде всего это касается скобок: в готовом регэкспе не должно быть лишних сохраняющих скобок. Модификаторы /i, /s, /m, /e и т.п. указываем, только если они нужны.Чтобы не допускать разброда в оформлении постов в закрома, присылайте их мне в почту: alienator@ya.ru, или пишите сюда — но не обижайтесь, если пост будет потёрт и заменен на иначе сверстанный.Под катом можно приводить набор тестовых строк, на которых выполняется и не выполняется регэксп.

Вторник, 2-е февраля

On Perl — блог о языке программирования Perl и его сообществе: Состоялся второй болгарский Perl-воркшоп

30 января в Софии прошел второй болгарский Perl-воркшоп. Первое мероприятие было проведено ровно год назад, 31 января 2009 года.

На этот раз посетителей и докладов было поменьше, но сам воркшоп от этого ничуть не пострадал. (Хотя, надо вспомнить офлайн № 17 Moscow.pm, размывший понятия воркшопа и встречи pm-группы.)

Воркшоп помогали организовывать Бойчо Бойчев и Мариан Маринов, который регулярно проводит конференцию по открытому ПО OpenFest, приезжал в Москву рассказывать про Gluster, и возил Джонатана смотреть окрестности Софии.

Выступлений было три, но все они получились продолжительными :-) Мариан рассказал про AnyEvent, Петар Шангов — про Catalyst, я — про Gearman.

На социальную часть людей пришло чуть ли не больше, чем на основную. Выяснилось, что случился локальный эпик фейл с анонсом. Каждую последнюю пятницу месяца в Софии проходит какое-либо IT-мероприятие, и обычно оно начинается в 13 часов. На одном из местных линуксовых сайтов анонс воркшопа висел под статической шапкой, где и было указано это время, хотя наше мероприятие началось в 11. На шапку посмотрели, а текст анонса не почитали.

Интересная деталь: среди участников (по крайней мере, социальной части :-) были отец и сын. Два поколения, старший — Пламен и младший — Николай. Отец, к тому же, говорил по-русски и много рассказал про Софию, про скользкие желтые кирпичи на центральной — «Желтой» — площади, про бывший проспект Ленина и нынешний Царя-освободителя, а заодно про македонцев, ментлитет итальянцев, англицизмы и русизмы в болгарском языке.

На следующий год мы планируем провести третье мероприятие про Perl в Болгарии, но сделаем это вместе с одним из регулярных IT-мероприятий в Софии.

Алексей Лихацкий: truncate string by length and word

Часто требуется обрезать строку по длине (ну возможно поставить в конце "..."). Проблема в том, что обрезание может попасть на часть слова, поэтому надо это слово обойти.

sub trunc {
    s/\s+?\S+?$//, return $_ for my $str = substr shift, 0, (shift || 1) + 1;
}
Вывод:
print trunc("11111 222  4444", 9);
#output: 11111 222
print trunc("11111 222  4444", 8);
#output: 11111

what_me: Бах!

Под музыку Баха отлично работается! С мысли не сбивает, спокойное настроение поддерживает. Вот уже несколько дней он фоном звучит. Доволен.

Понедельник, 1-е февраля

Язык_Perl | Сообщества на YVISION.KZ: Perl-way

Говорят, что хороший программист может писать Fortran на любом языке. =)» Мы не часто замечаем простые и очевидные вещи, потому что привыкли к многолетнему опыту написания кода на другом языке. Еще одна небольшая зарисовка на тему того, как писать Perl.

Дано: программа и командный интерфейс: создать, удалить, отредактировать. Пользователь пишет команду — программа делает то, что надо.

my $action = shift;

if ( $action eq 'create_node' ) {
# do some...
}
elsif ( $action eq 'edit_node' ) {
# do some more
}
elsif ( $action eq 'delete_node' ) {
# delete some
}

Довольно стандартная ситуация и стандартное решение.

А интрига в том, что на Perl можно написать совсем по-другому:

my $action = shift;

my $do = {
create_node => &create_node,
edit_node => &edit_node,
delete_node => &delete_node,
};
$do->{$action}->();

Вот такое простое решение, которое на 100% Perl-style =)». Ссылки на функции + хеш. В итоге получаем элегантное и расширяемое решение. Ну а у кого фантазия позволяет, может развить мысль дальше ;-)»

XPoint.ru | Программирование::Perl::Windows аспекты: Как установить CTPP2

Если кто устанавливал, поделитесь опытом. ОС WinXP Sp3

Ворота в Perl: HTML-Template и UTF-8

В процессе разработки одного модуля для внутренней системы заказчика, столкнулся с HTML-Template, UTF-8 и MSSQL. Все шло хорошо, пока не потребовалось вставлять в БД значения типа nvarchar, естественно юникодные, естественно на русском языке. Долго экспериментировал с DBIC, CGI-Simple (все эти модули были задействованы в проекте), и даже с типами данных в БД и кодировками файлов шаблонов, но проблема оставалась - в базе была полная абракадабра или в выводе клиенту - была полная абракадабра... То есть либо там либо там было все хорошо, но не вместе... Это меня навело на мысль, что проблема в шаблонах, а точнее в модуле их обрабатывающих.

В итоге созрел хак для модуля HTML-Template, сперва такой:

open(TEMPLATE,"<:encoding(utf-8)", $filepath);

А затем, благодаря Mons Anderson с moscow.pm, он был оптимизирован:

open(TEMPLATE,'<:utf8', $filepath);

Хакнутый модуль доступен здесь

 

P.S.

Тема неожиданно получила продолжение в списке рассылки moscow.pm. А именно, высказали опасения насчет безопасности использования второго способа с utf8. В качестве аргумента приводится статья: http://www.perlmonks.org/?node_id=644786. Думаю каждый сам решит для себя как лучше здесь поступить. В коде самого модуля вызов open(TEMPLATE...) встречается всего два раза - и желающие всегда смогут  изменить его на нужный вариант.

On Perl — блог о языке программирования Perl и его сообществе: Gearman (5) — презентация

В минувшую суботу показал болгарам, что такое Gearman :-)

Интересно, что про Gearman я впервые услышал от человека, пришедшего на собеседование в РИА Новости. Мы даже попросили тогда записать это слово на бумажке. Потом мы с Толей Стояновским пробовали использовать его для распараллеливания задач по сборке веб-страницы, но в итоге остановились на том, что будем использовать его «родственника» — другой продукт того же автора, TheSchwartz, который хранит задачи в базе данных, — и не для веба, а для служебной задачи «слива» новостей на серверы партнеров.

В то время Gearman-сервер был полностью написан на перле. Сегодня существует реализация на C, которую, очевидно, и нужно применять, и более того, созданы клиенты на C, Python, Java, C#, PHP и даже MySQL и PostgreSQL.

Заставить стабильно работать приложение с использованием Gearman, несмотря на всю простоту идеи и интерфейса, — может потребовать большого терпения. Тем не менее, это стоит попробовать и использовать. На голландском Perl-воркшопе в начале марта я хочу показать продолжение презентации, в которой расскажу о том, как использовать Gearman для веба.

Распределение задач с помощью Gearman. Январь 2010.


P. S. Очень удобный способ делать презентации: сначала месяц мусолишь в блоге по крохам тему, а потом на утро перед выступлением собираешь все вместе :-)

Воскресенье, 31-е января

http://juick.com/vti/514081

Как можно получить асинхронный орм в Mojolicious vti.showmetheco.de

Суббота, 30-е января

http://juick.com/vti/513568

Парсинг POD в Mojo github.com

Stupid notes on my fucking life: Белые пятна CPAN

Жду - не дождусь, когда в природе и на CPAN, в частности, появятся по-настоящему мужские модули, чтобы модным говнофреймворкописателям пусто было. Лично я бы прямо сразу примкнул к рядам благодарных пользователей XML::XQuery и еще чего-то похожего на XSD2DDL. А наблюдать за вереницей бесконечно бесполезных abstraction layers уже порядком заебало. В страшное время живем, товарищи...

Пятница, 29-е января

Сообщество ru_perl в LiveJournal: Вакансия Perl-программиста.

Быстрорастущей компании требуется в команду Perl-разработчик.

 
Область деятельности:
Мобильный интернет.
 
Основные задачи:
Самостоятельная творческая работа над новыми проектами компании.
 
Обязательные требования к кандидату на должность:
- знание Perl, HTML, CSS;
- знание SQL (MySQL).
 
Желательно наличие опыта и знаний в следующих областях:
XHTML;
Опыт работы с высоконагруженными проектами;
Хорошее знание MySQL.
 
Условия сотрудничества:
- удаленная работа на дому (в будущем, возможно, в офисе в Москве;
- полная занятность;
- график свободный;
- желательно проживание в Москве или ближайшем Подмосковье (хотя город не критичен);
- заработная плата от 60 000 руб./месяц и выше, зависит от опыта и знаний, обсуждается на собеседовании;
- премии по результатам работы.
 
Резюме направлять на nospamjob@gmail.com

On Perl — блог о языке программирования Perl и его сообществе: Пятничный лучок

Вчера двухсполовинойлетний Даниил Андреевич нарисовал вот такую штуку.

Чтобы снять неясность о том, что родитель увидел в рисунке своего ребенка, привожу рядом другую картинку — логотип с pm.org.

Сообщество ru_perl в LiveJournal: use CGI

Посоветуйте что-нибудь почитать про cgi.

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

sub create_form()
{
        print   $q->start_form;
        print   $q->p('Easy'),
                $q->textfield('foo','', 60, 120),
                $q->submit('Submit');
        print   $q->end_form;
}


Не понятно, как кнопке присвоить какое-либо действие и как это связать. С базой хоть всё понятно =)

Если подскажете, куда смотреть и что читать про работу cgi, буду очень благодарен.
Ну окромя perldoc, конечно.

Четверг, 28-е января

On Perl — блог о языке программирования Perl и его сообществе: Простой пример внедрения Gearman. Часть 3

Теперь настало время передвать более сложные аргументы, чем простые строки. Нет ничего проще — use Storable.

Перед тем, как передать задачу воркерам, упаковываем аргументы:

my $c = 0;
for (qw (red orange yellow green blue violet)) {
    $tasks->add_task(
       'search' => freeze([$c++, "$_ $text"]),
       {
         on_complete => \&search_completed
       }
    );
}

А внутри функции воркера — распаковываем:

my $request = thaw($job->arg);
my $result = MySearch::search($request->[1]);

После того, как получен результат, с ним потребуется произвести те же манипуляции, но в обратную сторону: заморозить (freeze) результат, вернуть серверу gearmand, а на клиентре — растопить (thaw).

Правда или нет, но передача данных от воркера в вызывающую задачу — глючит (особенно в Gearman::XS::Worker), да и бесконечные freeze/thaw только уродуют код. Намного удобнее, если воркер не будет ничего возвращать, а вместо этого складировать свои результаты в общее хранилище (например, в базу данных), доступное вызывающему приложению.

koorchik's Perl blog: Инструменты разработчика: Devel::TraceUse

Модуль позволяет посмотреть(в виде дерева) какие модули подключает ваша программа. 
Это бывает может быть полезным в разных случаях. Например,  когда  программа сразу после компиляции начинает занимать слишком много памяти...  или бывает непонятно какой из бекендов подключает некий модуль(например JSON)... или просто необходимо собрать список зависимостей  ...  В общем - вариантов может быть масса.
В любом случае попробуйте запустить программу вот так: perl -MDevel::TraceUse myprog.pl, возможно будете удивлены.

Пример вывода:
perl -MDevel::TraceUse -MFindBin -e ''
Modules used from -e:
  FindBin, line 0 (4.8e-05)
    Carp, line 95 (3.9e-05)
    Cwd, line 98 (4.1e-05)
      XSLoader, line 247 (5.3e-05)
    File::Basename, line 99 (5.6e-05)
      re, line 44 (3.8e-05)
    File::Spec, line 100 (4e-05)
      File::Spec::Unix, line 22 (3.6e-05)

Сообщество ru_perl в LiveJournal: cgi =&gt; ?

Доброе время суток,
есть внутренняя админка в которой больше 100 разных cgi скриптов, работает всё как обычно через apache2 cgi, хочется минимумом усилий на что-то перевести чтоб работало нормально, т.е. быстрее, но без фанатизма, при этом переделывать всё под mod_perl'овский PerlHandler ну очень обломно.. как бы переделать всё и на что переделать?

ЗЫ: на пхп и т.д. переходить это всё не будет, постоянно появляются новые скрипты или что-то меняется, поэтому гемора не хочется с конфигами апача)

Кодекс кодоголика: Кури RFC, %username%!

Люблю я в своей работе использовать модуль Regexp::Common, созданный незабвенной Abigail!

А ЗРЯ :-E

$ perl -MRegexp::Common -le 'print "www.610.ru" =~ /^$RE{net}{domain}{-nospace}$/ ? 1 : 0'
0

Это обыкновенный промышленный саботаж. И главное, ведь не подкопаешься: всё в соответствии с RFC.

Кстати, для тех, кто не знает, що таке {-nospace}, подывытыся:

$ perl -MRegexp::Common -le 'print " " =~ /^$RE{net}{domain}$/ ? 1 : 0'
1

Призываю создать в культуре Perl новое движение — RFC-нацизм, Abigail назначить его бессменным лидером, модуль переименовать в Regexp::Uncommon и использовать для пыток инакомыслящих.

Среда, 27-е января

On Perl — блог о языке программирования Perl и его сообществе: Простой пример внедрения Gearman. Часть 2

Переделка скрипта для работы с Gearman весьма проста, если решение задачи запрограммировано таким образом, чтобы у нее были только вход и выход :-) В случае со вчерашним примером функция поиска, помещенная в воркер, состоит из двух строк:

sub search {
    my $job = shift;

    return MySearch::search($job->arg);
}

Клиентский код несколько усложняется: сначала необходимо создать пул задач, а затем дождаться их выполнения:

for (qw (red orange yellow green blue violet)) {
    $tasks->add_task(
        'search' => "$_ $text",
        {
            on_complete => \&search_completed
        } 
    );
}
$tasks->wait;

Сбор данных по окончании каждой задачи тоже крайне прост:

sub search_completed {
    my $result = shift;
   
    $html_result .= $$result;
}

Теперь осталось запустить с десяток отдельных воркеров, и скорость работы тестового скрипта возрастает на порядок: последовательные запросы на поиск картинок шести цветов зарубежной радуги завершались за 1-3 секунды, после модернизации — за 0,1-0,6. Задачи параллелятся на ура, но важно понимать, что это имеет смысл только для тех задач, которые по своей природе проводят много времени в ожидании ответа, не тратя процессорное время локальной машины.

Perl6.ru: Хакатон, посвященный Perl 6

Открылась регистрация на хакатон Perl 6 Hackathon 2010 года, посвященный Perl 6. Мероприятие состоится в Копенгагене 6 марта.

i-t-шные заметки: Is perl dead ?

isperldead.com

Вторник, 26-е января

koorchik's Perl blog: Движки сериализации: кто быстрее?

Сегодня наткнулся на модуль Benchmark::Serialize, который тестирует разные движки сериализации(
тестируется сериализация, десериализация и размер сериализированных данных).

У меня в системы оказались следующие движки: Data::Dumper 2.124, JSON::PP 2.27000 JSON::XS 2.27, Storable 2.20, XML::Simple 2.18. 

И я был очень и очень удивлен результатом. Первое место по всем показателям достается модулю JSON::XS, при десериализации он быстрее Storable на 30%, а при сериализации в целых 6 (!!!) раз. Размер данных тоже минимальный.

Привожу результаты (исходник бенчмарка в атаче)
               Size     Deflate    Inflate
JSON::XS       376     313980/s   139750/s   
JSON::PP       376       5307/s     1778/s    
Storable       382      46848/s   109720/s    
XML::Simple    502       4912/s     1249/s 
Data::Dumper   1058     15486/s    18719/s


            


On Perl — блог о языке программирования Perl и его сообществе: Простой пример внедрения Gearman. Часть 1

На болгарском Perl-воркшопе я хочу немного рассказать о том, как на практике обрабатывать задачи, используя Gearman.

Один из примеров — последовательная трансформация кода: сначала цикл, потом параллельный вызов нескольких воркеров, затем попытка использовать внутри воркеров общие данные.

Отдельная задача минимальна: для заданного запроса $text найти на гугле несколько картинок разного цвета. В первом случае, когда используется цикл, работает такой код:

for (qw (red orange yellow green blue violet)) {
    $html_result .= MySearch::search("$_ $text");
}

Я хочу показать, как эти запросы распараллелить, передав их разным воркерам, работающим на разных машинах. А следующий шаг — научить независимые воркеры использовать общие данные, используя либо memcached, либо дополнительный неблокирующий воркер.

Сообщество ru_perl в LiveJournal: mod_perl

Приветствую.

Такой вопрос, допустим сайт работает на mod_perl, есть обработчики, которые отвечают за разные разделы сайта и т.д.
Обработчики загружаются один раз и все время висят в памяти, модули, которые вызываются через use, тоже зависают в памяти, а память — критический параметр. В голову приходит только оставить костяк системы в памяти, а некоторые модули подгружать на время их вызова и выгружать сразу же из памяти. Что вообще в таком случае делают на mod_perl?

Сообщество ru_perl в LiveJournal: Производительность UDP-сокетов в Perl

Запускаю написанный на PERL коллектор Netflow,
взятый с http://www.mindrot.org/projects/pfflowd/
(прямой линк - http://www.mindrot.org/files/pfflowd/collector.pl)

Для работы с UDP-сокетом в нём используется IO::Socket::INET.
Обнаруживаю, что даже с закомментированным парсингом пакетов коллектор пропускает пакеты:
300 пакетов tcpdump поймал за 42 секунды, а коллектор за 44.36 сек.

Общая загрузка CPU другими процессами - около 20%, ОС FreeBSD 6.2, perl 5.8.8.

Вопрос: поможет ли замена IO::Socket::INET на чистый perlipc
в духе http://perl.active-venture.com/pod/perlipc-udp.html ?

Если нет, то как (и можно ли вообще) на PERL принимать UDP без пропусков?
Про flow-tools, естественно, знаю, но мне хотелось бы на лету классифицировать трафик
по пользователям и направлениям, а для этой задачи PERL оптимален.

Понедельник, 25-е января

On Perl — блог о языке программирования Perl и его сообществе: YAPC::Europe 2010

Объявлены даты проведения конференции YAPC::Europe 2010. Конференция пройдет в Пизе с 4 по 6 августа. Место проведения — конференц-центр гостиницы Moh Galilei. Тема — The Renaissance of Perl.

koorchik's Perl blog: Генерация произносимых паролей

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

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

Был выбран модуль Text::Password::Pronounceable, результатом работы которого я остался очень доволен.
Модуль простейший, и вся возможности помещаются в два следующих примера генерации произносимого пароля длиной 6-10 символов
пример 1:
Text::Password::Pronounceable->generate(6, 10); 
пример 2:
my $pp = Text::Password::Pronounceable->new(6, 10);  
$pp->generate

Примеры сгенерированных  паролей:
theoro ortofi nditost coftodt thagorth taprnthi ingingr linesror destro icerarado

ЗЫ:  Мне всегда нравились каптчи(CAPTCHA) гугла тем, что они читабельны и этот модуль можно использовать также для генерации текста "вменяемых" каптч.
ЗЫ2: Для генерации более надежных паролей можно использовать Text::Password::Pronounceable::Harden

Алексей Капранов: Please!

$ perl -please /etc/passwd

Read and post comments | Send to a friend

Сообщество ru_perl в LiveJournal: Разбор строки

Здравствуй кмьюнити!
Есть давлольно простая задача. Нужно распарсить строку вида (размер строки произвольный):
'name1' val1 'name2' val2 ...


все данные поместить в массив из анонимных массивов:
[
    [name1, val1],
    [name2, val2],
    ...
]

Сделать всё это нужно максимально быстрым способом (имеется ввиду время выполнения кода).

Сразу хочу отметить, пользоваться сампоисанными модулями использующие C, Xs запрещается, так же нельзя использовать нестандартные модули или строноннии программы.

Исходя из этих усолвий, на ум пришло несколько решений, но их скрорость не сильно удовлетворяет =( Вот собственно код этих решений:

#!/usr/bin/perl -w
use strict;

use Benchmark ':all';

my $str = "'xxx' zzz 'yyy' mmm 'sdfg' oelflv";

cmpthese (10000, { test0 => \&test0, test1 => \&test1, test2 => \&test2, test3 => \&test3 } );

sub test0 { my $str_buff = $str; my @result_list = (); while($str_buff =~ m/'([a-zA-Z0-9]+)' ([a-zA-Z0-9]+)/g) { push @result_list, [$1,$2]; } return \@result_list; }

sub test1 { my @array = map {chr($_)} unpack('C*',$str); my $length = scalar @array; my $i; my $name; my $val; my @result_list = (); for($i=0;$i<$length;$i++) { $i++; $name = ''; $val = ''; for(;$i<$length;$i++) { last if($array[$i] eq '\''); $name .= $array[$i]; } $i++;$i++; for(;$i<$length;$i++) { last if($array[$i] eq ' '); $val .= $array[$i]; } push @result_list, [$name,$val]; } return \@result_list; } sub test2 { my $exit_flag = 0; my $index_old=0; my $index_new; my $name; my $val; my @result_list = (); while(!$exit_flag) { $index_old++; $index_new = index($str, '\'', $index_old); $name = substr($str,$index_old,$index_new-$index_old);

$index_old = $index_new; $index_old +=2; $index_new = index($str, ' ',$index_old); if($index_new >= 0) { $val = substr($str,$index_old,$index_new-$index_old); $index_old = $index_new; $index_old++; } else { $val = substr($str,$index_old,length($str)-$index_old); $exit_flag = 1; } push @result_list, [$name,$val]; } return \@result_list; }

sub test3 { my $string = $str; my $index; my $name; my $val; my @result_list = (); while(length $string) { substr($string,0,1) = '';

$index = index($string, '\''); $name = substr($string,0,$index); substr($string,0,$index+2) = '';

$index = index($string, ' '); if($index >= 0) { $val = substr($string,0,$index); substr($string,0,$index+1) = ''; } else { $val = $string; $string = ''; } push @result_list, [$name,$val]; } return \@result_list; }



В результате этого теста получается, что пока чемпион - тест номер 2:
        Rate test1 test3 test0 test2
test1  271/s    --  -76%  -78%  -81%
test3 1152/s  325%    --   -7%  -20%
test0 1238/s  357%    7%    --  -14%
test2 1439/s  431%   25%   16%    --


Ещё, был вариант, прикрутить кэширование, так как иногда строки могут повторятся.
Так же был вариант для коротких строк использовать один метод, а для более длинных другой (например, вриант из теста номер 1 для коротких, а вариант из теста номер 2 для более длинных), но в обоих категориях код теста номер 2, показал себя с лучшей стороны.

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

Хабрахабр: Метки / perl: Я пиарюсь / Позвольте представить — Записки программиста

Интернет-журнал Записки программиста главным образом посвящен таким непростым вещам, как unix-like системам (главным образом — FreeBSD) и программированию на С/C++ и Perl. Тем не менее, я стараюсь время от времени писать посты, рассчитанные на бОльшую целевую аудиторию, потому, надеюсь, блог заинтересует многих.

Чуть подробнее — под катом.

Сообщество ru_perl в LiveJournal: Как правильно разместить кириллицу в модуле для CPAN?

На CPAN есть модули, в исходном тексте которых встречается кириллица — выглядит странно: очень часто она хранится в какой-нибудь восьмибитной кодировке типа CP1251 — в результате вместо русского текста отображаются латинские буквы с диакритическими знаками. Я собрался выложить на CPAN свой модуль (где встречатся кириллица) и задумался — как же правильнее использовать в коде русские буквы?

Понятно, что можно засунуть их как есть (то есть, кириллица останется). Можно использовать \N{буква} (мы избавимся от кириллицы, но код станет более громоздким):

#!/usr/bin/perl -wl -CO
use utf8;
use charnames qw(cyrillic);

print join "\t", qw(ноль раз два три)[2], "\N{Ka}\N{i}\N{er}\N{i}\N{el}\N{el}\N{i}\N{tse}\N{a}", ("\N{ya}", "\N{te}\N{yeru}")[1];

Такой пример вполне работоспособен:
два Кириллица ты
Но вот внутри qw// последовательность \N{буква} никоим образом не обрабатывается:
print join '-', qw(\N{ya} \N{te}\N{yeru});
\N{ya}-\N{te}\N{yeru}
Как быть? Хочется, чтобы было и компактно, и корректно.

Воскресенье, 24-е января

Shoor/нал: Перловый юникодный транслитератор

Дёшево и сердито (ну да, даже в перлдоке на модуль написано — quick and dirty)

#!/usr/bin/perl -nl -CD
use Text::Unidecode;
print unidecode( $_ );
Кириллицу успешно перекодирует. Используемые правила транслитерации слегка необычны: г→gh, e→ie, твёрдый знак вообще пропадает. Но всё равно получающийся текст достаточно понятен.

Сообщество ru_catalyst в LiveJournal: Простой трансформер для HTML::FormFu

Я пока что обломался делать к нему всю положенную обвязку, если кому нужно - берите.

package HTML::FormFu::Transformer::PassHash;
use strict;
use warnings;
use base qw(HTML::FormFu::Transformer);
use Digest;
use Moose;

__PACKAGE__->mk_item_accessors(qw(digest password hash));

sub transformer { my ($self, $value) = @_; return unless $value gt ''; # Bail out if no password entered my $hash = uc($self->hash()) || 'MD5'; my $hashed; my $pfield; eval { my $dobj = Digest->new($hash) or die 'Unknown hash: '.$hash; $pfield = $self->password() or die 'Undefined password hash field'; my $dtype = $self->digest(); $dobj->add($value); eval { # It should be done some smarter way if ($dtype eq 'hexdigest') { $hashed = $dobj->hexdigest(); } elsif ($dtype eq 'digest') { $hashed = $dobj->digest(); } elsif ($dtype eq 'b64digest') { $hashed = $dobj->b64digest(); } else { die 'Unknown digest :', $dtype; } }; if ($@) { die "Cannot make $dtype: $@"; } }; if ($@) { die HTML::FormFu::Exception::Transformer->new({ message => $@ }); }

$self->form->add_valid($pfield => $hashed); return $value; }

1;



После этого в form.yml

  - type: Password
    name: password
    label: Password
    transformers:
      - type: PassHash
        password: passmd5
        hash: MD5
        digest: hexdigest




В результате отработки трансформера с указанным примером формы, в поле passmd5 ложится MD5 hexdigest от поля password, если поле непустое.

Мета

Поиск

Участники

Список участников в формате OPML OPML

Добавить сайт

По-другому

Приборы

Rambler's Top100