Минимальный набор Perl-мероприятий, которые мне хочется посетить в наступающем году.

Минимальный набор Perl-мероприятий, которые мне хочется посетить в наступающем году.

Разбить текст на предложения — довольно распространенная задача. (Часто возникает схожая задача — выделить одно-два первых предложения.)
На спане есть несколько модулей, которые частично решают задачу. К сожалению, некоторые модули просят установить локаль (в наш век юникода), однако на поверку вполне уверенно работают и с русскими текстами безо всяких локалей.
Мне хочется, чтобы на входе был UTF-8, и не разрывались части предложения типа А. С. Пушкин, а еще лучше — зал им. А. Пушкина.
Модуль входит в состав комплекта HTML::Summary. Без установки локали в русских текстах лихо пропускает половину точек (да, я нагло тестировал юникод).
use Text::Sentence qw(split_sentences);
my @s = split_sentences($text); # возвращается список
use Lingua::EN::Sentence qw(get_sentences);
my $s = get_sentences($text); # возвращается ссылка на список
Несмотря на название, модуль уверенно выделяет русские предложения, и не разбивает инициалы. Не прошел тест на немецкую дату 30. Dezember (разбил на точке), но на это есть другой модуль. Зал им. А. С. Пушкина поделил на части после им.
use Lingua::DE::Sentence;
my $s = get_sentences($text); # ссылка на список
Работа и результаты похожи на английский аналог, но с немецким форматом дат все в порядке.
Свежачок: модуль, добавленный на спан позавчера.
use Text::ToSentences qw(convert);
my $s = convert($text);
Функция convert возвращает ссылку на список предложений.
Здесь все хорошо с юникодом, но из зала им. А. С. Пушкина получислоь четыре предложения.
У этого модуля есть особенность — он выделяет из предложений части, заключенные в скобки, и помещает их в итоговый список как самостоятельное предложения (удаляя из охватывающего).
P. S. Это была история о том, почему рождаются велосипеды :-)
Сегодня на спане появился модуль Gearman::Driver, который, судя по документации, помогает создавать ООП-подобную иерархию воркеров и экономить память на том, что общие части объектов используются совместно — дочерние воркеры запускаются в едином процессе. Дополнительно имеется возможность автоматически клонировать новые воркеры по мере надобности.
Вроде все хорошо, только стало не по себе, когда при установке модуля потребовались не только Gearman::XS (гуд), но и Moose вместе с MooseX, и POE (бэд).
Warning: prerequisite Gearman::XS 0.7 not found.
Warning: prerequisite Module::Find 0.08 not found.
Warning: prerequisite Moose 0.93 not found.
Warning: prerequisite MooseX::Getopt 0.26 not found.
Warning: prerequisite MooseX::Log::Log4perl 0.40 not found.
Warning: prerequisite MooseX::MethodAttributes 0.18 not found.
Warning: prerequisite MooseX::Types::Path::Class 0.05 not found.
Warning: prerequisite Net::Telnet::Gearman 0.01000 not found.
Warning: prerequisite POE 1.280 not found.
Недавно на спане появился модуль HTML::DOM, который одновременно — и парсер и билдер. Пара первых простейших экспериментов с этим модулем.
Создание HTML
use v5.10;
use strict;
use HTML::DOM;
my $dom = new HTML::DOM;
$dom->write('<html>');
say $dom->innerHTML;
Здесь модуль создаст HTML с полным набором нужных тегов:
<html><head></head><body></body></html>
Более того, правильно обрабатываются и неправильные вызовы, например такой код
$dom->write('<html>');
$dom->write('<title>My Title</title>');
аккуратно размещает тег <title> внутри <head>:
<html><head><title>My Title</title></head><body></body></html>
Чтение HTML
Базовая операция чтения файла проста:
use v5.10;
use strict;
use HTML::DOM;
my $dom = new HTML::DOM;
$dom->parse_file('test.html');
say $dom->innerHTML;
Опять же, происходит внятное преобразование до валидного HTML-кода. Если файл test.html содержит одну строку <title>My Title</title>, то на выходе получается следующее:
<html><head><title>My Title</title>
</head><body></body></html>
Этими примитивными действиями модуль не ограничивается. В его распоряжении набор методов, напоминающих методы, доступные в XML::LibXML и при обработке DOM с помощью JavaScript.
Этот пост — сотый на этом сайте.
Первая запись появилась здесь 12 августа этого года, а затем каждый рабочий день появлялась новая. Я пропустил лишь два или три дня, и пару раз опубликовал два поста за один день. Все записи написаны самолично :-)
17 апреля на скандинавском Perl-воркшопе в Осло Мэтт Траут объявил о проведении соревнования Iron Man Blogging Challenge. Он предложил участникам Perl-сообществам регулярно писать про Perl в свои блоги, увеличив таким образом массу записей про Perl. Сегодня в списке авторов, которые зарегистрировались на Iron Man, 498 имен (включая несколько повторов, когда один человек регистрирует несколько своих блогов).
28 сентября Алекс Капранов открыл сайт planetperl.ru, аггрегирующий записи о перле на русском языке.
С 1 по 25 декабря прошла волна Perl-адвентов — это серии ежедневных публикаций про Perl, приуроченные к западному Рождеству (как раз сегодня):
Второй год в течении всего ноября Карл Мэсак пишет ежедневные посты на use.perl.org. (Месяц выбран по названию вики-движка на Perl 6).
А я пишу каждый день — не привязываясь ни к каким конкурсам и грядущим праздникам :-)
Воркеры и клиенты, подключенные к серверу gearmand, работают «сами по себе», и отслеживать, что где происходит без дополнительного отладочного вывода не очень удобно (а мониторить хочется).
В протоколе Gearman есть команда status, в ответ на которую сервер выдает список зарегистрированных воркеров, сообщает их число, а также число выполняемых задач и длину очереди.
Самый простой способ — подключиться к gearmand телнетом, и послать команду status:
# telnet localhost 4730
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
status
echo2 1 1 2
echo 5 2 5
.
В ответ сервер печатает список зарегистрированных функций (в показанном примере — echo и echo2) и для каждого — три показателя: число исполняемых задач, число задач в очереди и число доступных воркеров.
(Если выполняется одна задача, и при этом нет ни одного клиента, ожидающего ту же функцию, то почему-то в очереди все равно стоит единица.)
Вопрос о том, как мониторить задачи, недавно поднимался в рассылке про Gearman, — там же приведен пример Perl-скрипта, который выводит статус по запрошенному имени функции. Пример может послужить (как это и было со мной) отправной точкой к тому, чтобы понять, как работать с gearmand по телнету :-)
Английское слово venue я узнал только когда поехал YAPC::Europe в 2007 году :-) А вот список того, где мы делали наши перловые мероприятия.
Perl Today, Москва. Помещение — зал (одна стена и потолок) в «Крокусе» во время выставки «Инфоком-2007», который нам на день бесплатно выделил «Линукс-центр». На столах были компьютеры, но было шумно, а вокруг постоянно ходили люди. Тяжело добраться от города (метро около «Крокуса» еще не было :-).
Perl Mova, Киев. Аренда пресс-центра «Украинских новостей». Очень мило, хотя и дорого; записали звук с микрофона. Кофе-брейк делать было негде.
May Perl, Москва. Две аудитории в здании ГУ-ВШЭ в Кирпичном переулке. Одна на девятом этаже — отличный зал «амфитеатром», вторая — обычная аудитория на шестом. В большой экран висит прямо перед окном, правда. Довольно далеко от метро, но зато кофе-брейк не отходя от кассы.
Far East Perl, Владивосток. Компьютерная аудитория Владивостокского государственного университета экономики и сервиса. Оценить, удобно ли было добираться, не могу, поскольку довезли до места, а города я не знаю :-) Зал с компьютерами, но в центре столб. Бесплатно.
BY Perl, Минск. Помещение в гостинице организовала компания «Агава». Забыли вовремя арендовать проектор, и в субботу гостиница не смогла отпереть дверь, за которой они хранят проектор, потому что выходной день. За час-полтора нашли ребят, которые привезли нам проектор за двойную плату. О том, как я договаривался о кофе-брейке — отдельная история: «Нам нужен кофе-брейк на 20 человек» — «Сделаем». Это «Сделаем», которое произнес администратор гостиничного ресторана, — чисто фраза из советского фильма, где люди полуподпольно договариваются о дефицитных товарах. От моей гостиницы было близко, но минские расстояния очень обманчивы.
South Perl, Ростов-на-Дону. Аудитория факультета математики, механики и компьютерных наук Южного федерального университета. Аудитория со столами «лесенкой», правда слишком большая и вместительная. На сцене были колонки и пианино. Как добирались, хз :-)
BG Perl, София. Софийский университет, Французский институт культуры. Аудитория со стеклянными стенами, совмещенная с небольшой библиотекой. Была забита до отказа. Поскольку в Софии центра нет, то можно считать, что помещение было в центре города :-)
Perl Mova — 2, Киев. Помещение бесплатно предоставил G-Club компании Global Logic. Часть зала занимали места для зрителей, часть — спортивные тренажеры, часть — кухня и бильярд. До места не слишком удобно добираться, да и вообще найти входную дверь, но зато это было самое необычное помещение, да к тому же бесплатное. Спасибо, G-Club.
Perl Tashkent, Ташкент. Нам дали аудиторию в Ташкентском университете информационных технологий, а само мероприятие было в рамках выставки «Best Soft — Узбекистан». Погода — жара.
May Perl — 2, Москва. По вторму кругу две аудитории ГУ-ВШЭ, но уже две аудитории «амфитеатром», удобно размещенные рядом с друг другом (и столовой).
BY Perl Too, Минск. Помещение в офисе компании EPAM Systems. Воркшоп был в субботу, и в здании было пустынно. В туалет ходили по карточкам :-)
Baltic Perl Workshop, Рига. Конференц-зал в отдельно стоящем здании во дворе гостиницы Konventa Sēta. Очень недурно, хотя и со столбами в зале. Два кофе-брейка принесли четко по расписанию. Цена вполне приемлемая.
Казахстанский Perl-воркшоп, Кустанай. Аудитория Костанайского государственного университета. Стены и коридор вполне университетские :-), но зато в аудитории установлен проектор и активный (на нем можно рисовать) экран.
Saint Perl, Санкт-Петербург. Аудитория математико-механического факультета Санкт-Петербургского государственного университета. Нормальное помещение, правда без вайфая, хотя и с розетками около каждой парты. 50 минут на электричке от города (компенсируется наличием «Сапсана» :-)
BG Perl — 2. Там же, где и год назад.
Perl Mova — 3 + YAPC::Russia 2010. У меня сегодня родилась идея арендовать корабль и поплавать летом по Днепру.
В XML::LibXSLT существует возможность обращаться к коду на Perl. Я ни разу не пользовался такой возможностью, поскольку обычно удается решить задачу более простым способом, сформировав все нужные данные до того момента, когда управление будет передано XSLT-процессору.
Тем не менее, интересно посмотреть (и я даже нашел применение), как воспользоваться такой возможностью.
В примере изначально упорядоченные данные из XML-файла выводятся в случайном порядке.
XML имеет такой вид:
<?xml version="1.0"?>
<data>
<item>alpha</item>
<item>beta</item>
<item>gamma</item>
</data>
А XSLT-преобразование — такой:
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:perl="urn:perl">
<xsl:template match="/data">
<xsl:for-each select="item">
<xsl:sort select="perl:random()"/>
<xsl:value-of select="text()"/>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Здесь выполняется сортировка узлов item в порядке, заданном инструкцией xsl:sort, которая обращается к фукнции perl:random(), которую следует определить и зарегистрировать в парсере XML::LibXML:
use v5.10;
use strict;
use XML::LibXML;
use XML::LibXSLT;
my $xml_parser = new XML::LibXML;
my $xslt_parser = new XML::LibXSLT;
$xslt_parser->register_function('urn:perl', 'random', sub {rand()});
my $document = $xml_parser->parse_file('./data.xml');
my $transform = $xslt_parser->parse_stylesheet_file('./transform.xsl');
my $result = $transform->transform($document);
say $result->toString();
Функция, ссылка на которую указана при вызове register_function, должна возвращать текстовую строку. Имя пространства имен может быть, разумеется, любым, удобным разработчику.
Вывод нескольких последовательных запусков показанного примера в моем случае выглядел так, как и ожидалось (XML-заголовок не показан):
beta, alpha, gamma
gamma, alpha, beta
gamma, alpha, beta
beta, alpha, gamma
beta, gamma, alpha
Известно где работал вот такой код, который по географическим координатам двух точек на Земле определял расстояние между ними:
my $gis = new GIS::Distance;
my $distance = $gis->distance(@coords_pair);
. . .
add_node{$node, 'pair', {
. . .
distance => int($distance + 0.5),
});
В переменной $distance — вычисленное расстояние в километрах, которое округляется и передается функции add_node, чтобы построить XML-узел, вписав расстояние в одноименный атрибут.
Через пару дней мне захотелось показывать, какую часть экватора составляет найденное расстояние. Что может быть проще?
my $fraction = $distance / 40_075.696;
add_node{$node, 'pair', {
. . .
fraction => $fraction,
distance => int($distance + 0.5),
});
Посмотрел на результат, и вижу, что расстояние между Питером и Пекином — 15% длины экватора. Отлично. Но что такое?! — и само расстояние стало 15 километров.
Так и появился бы еще один седой волос, но warn ref $distance легко ответило на вопрос «какого?»:
Class::Measure::Length at /home/ash/. . ./Place/Worker.pm line 493.
Переменная $distance — ссылка на объект типа Class::Measure::Length; такого же типа становится и переменная $reference. Фактически обе переменные указывают на одно и то же. Когда я делю расстояние на длину экватора и сохраняю результат в $reference, я тем самым порчу значение, которое — как я думал — содержится в переменной $distance.
Оказалось, что Class::Measure, от которого унаследован Class::Measure::Length, одним из первых действий переопределяет пять операторов:
use overload
'+'=>\&_ol_add, '-'=>\&_ol_sub,
'*'=>\&_ol_mult, '/'=>\&_ol_div,
'""'=>\&_ol_str;
Как бы я ни пользовался переменной $distance — пытался бы интерполировать его в строке или использовал бы в арифметических выражениях, всегда инициировались переопределенные операторы.
Смотрим на поведение на изолированном примере:
use v5.10;
use strict;
use Class::Measure::Length;
my $m = new Class::Measure::Length(1, 'inch');
my $f = int($m + 0.5);
say $m;
Здесь последовательно вызываются три метода:
_ol_add
_ol_str
_ol_str
Первые два приходятся на строку
my $f = int($m + 0.5);
Сначала вычисляется сумма _ol_add($m, 0.5), а затем результат (типа Class::Measure::Length) стрингифицируется.
Возвращаясь к исходной задаче, видно, что решение-то простое: нужно лишь воспользоваться методом value, чтобы получить расстояние как число:
my $distance = $gis->distance(@coords_pair)->value;
После этого никаких фокусов при делении не проиходит. Всего-то одно сомнительное решение разработчика модуля, и полчаса ненужной отладки в неожиданном месте.
05:50 утра, Москва, новый терминал «Шереметьево — D». Анатолий Шарифулин готовит доклад про Mojo и пытается не запачкать новый пол зала ожидания.

В магазинах появился русский перевод книги O’Reilly «Регулярные выражения. Сборник рецептов» (Regular Expressions Cookbook), написанная Яном Гойвертсом и Стивеном Левитаном.

(На оригинальной книге, которую я получил от O’Reilly, тоже есть черная полоса с надписью Includes a Regular Expressions Tutorial.)
Содержание
Все примеры в рецептах даны на семи диалектах регулярных выражений: .NET, Java, JavaScript, PCRE, Perl, Python и Ruby.
Цена на books.ru вдвое меньше (650 руб.), чем в «Московском доме книги» (1135 руб.).
Не первый год в Perl 5.10 есть оператор смартматчинга ~~, но я до сих пор не знал, где бы его применить. На днях Толя Шарифулин написал о том, как этот оператор использовать вместо grep.
А я, наконец-то, придумал, зачем мне это может потребоваться. Время от времени служебным утилитам требуется передавать опции, но читать их через Getopt::Long не очень хочется: во-первых, каждый раз приходится вспоминать синтаксис, а во-вторых, для коротких командных скриптов хочется более простого решения. Смартматчинг как раз его и дает:
say 'Debug' if '--debug' ~~ @ARGV;
say 'Daemon' if '-d' ~~ @ARGV;
Так же просто поискать ключ с помощью регулярного выражения:
say 'Help' if /^(-h|--help)$/ ~~ @ARGV;
Осталось придумать, как выделять аргументы ключей, например: -p 30.
И ссылка для привлечения внимания: smart-matching.com :-)
Опубликовано расписание докладов на четвертом российском Perl-воркшопе «Saint Perl 2009», который пройдет в 22-й день рождения Perl 18 декабря 2009 года в Санкт-Петербурге.
«Saint Perl 2009» — 14-е мероприятие цикла YAPC::Russia. Полный список мероприятий и ближайшие планы — на сайте yapcrussia.org.
Для работы с сервером gearmand помимо модулей на перле удобно воспользоваться и XS-вариантами Gearman::XS.
На спане есть модули для всех трех частей рабочей среды — серверов, воркеров и клиентов — однако в реальности скорее всего не возникнет необходимости в модуле Gearman::XS::Server, работающего сервером; достаточно воспользоваться XS-переходниками для воркера (Gearman::XS::Worker) и клиента (Gearman::XS::Client).
Создать и воркер, и клиент почти также просто, как и их pure-Perl-аналоги. Некоторое неудобство может вызвать C-подобный стиль обработки ошибок, который показан в самом начале документации.
Минимальный вариант воркера, экспортирующего функцию echo, которая увеличивает на единицу полученный аргумент, выглядит так:
use v5.10;
use strict;
use Gearman::XS::Worker;
my $worker = new Gearman::XS::Worker;
$worker->add_server('127.0.0.1', 4730);
$worker->add_function('echo', 0, \&echo, undef);
$worker->work() while 1;
sub echo {
my $job = shift;
return $job->workload() + 1;
}
Клиентская часть, синхронно вызывающая метод echo:
use v5.10;
use strict;
use Gearman::XS::Client;
my $client = new Gearman::XS::Client;
$client->add_server('127.0.0.1', 4730);
my ($ret, $result) = $client->do('echo', '15'); # arg as string!
say $result;
Следует обратить внимание на два момента. Во-первых, вызов возвращает две величины — код завершения $ret и собственно результат $result. Во-вторых, в качестве аргумента следует передавать именно строку, даже если (как в показанном примере) аргумент — число (иначе метод вернет 2 вместо 16).
Наконец, асинхронный вариант постановки нескольких задач:
use v5.10;
use strict;
use Gearman::XS::Client;
my $client = new Gearman::XS::Client;
$client->add_server('127.0.0.1', 4730);
my ($ret1, $task1) = $client->add_task('echo', '15');
my ($ret2, $task2) = $client->add_task('echo', '51');
$client->run_tasks();
Эта программа завершается по окончании обеих задач, но задачи можно написать так, что возвращаемый результат не нужен (а получить из переменных $task1 и $task2 после завершения задач уже ничего не получается: Segmentation fault на любую попытку взять из них данные после выполнения задачи; а может зря я в самом начале отмел Gearman::XS::Server?).
Выдержка из свежего прямого эфира на «Составе».
10.12.2009 14:41 Кост
— Антон Вы имеете опыт работы на языках программирования?
10.12.2009 23:43 Антон Носик
— Да, в 1995 году приходилось изучать PERL, и что-то на нём писать. Но у меня мозги под программирование плохо заточены.
Среди «погодных» модулей на спане есть и модули для работы с форматами, которые используются в авиации. В частности, несколько модулей для разбора форматов METAR (однозначной расшифровки аббревиатуры не существует) и TAF (Terminal Aerodrome Format).
Данные в формате METAR по аэропортам можно получить, например, на сайте National Weather Service. (О кодах аэропортов уже говорилось). Строка с закодированной информацией о текущей погоде в Шереметьеве (UUED) выглядит так:
UUEE 111930Z 08005MPS 9999 -SN BKN011 M07/M09 Q1029 NOSIG RMK 57410151 07410151
Пользоваться модулем весьма просто:
use v5.10;
use strict;
use Geo::METAR;
my $metar = new Geo::METAR;
$metar->metar($ARGV[0]);
say $metar->dump;
Вызов dump печатает всю имеющуюся информацию, в то время как доступ к отдельным параметром осуществляется через индивидуальные имена, например:
say $metar->TEMP_C; # температура в градусах Цельсия
say $metar->DEW_C; # точка росы
Эти строки напечатают «голые» значения, например: -07 и -09.
Несмотря на название, модуль Geo::TAF способен разбирать и формат METAR:
use v5.10;
use strict;
use Geo::TAF;
my $taf = new Geo::TAF;
$taf->metar($ARGV[0]);
say $taf->as_string;
С упомянутой выше строкой (если ее предварить словом METAR, то вместо вызова одноименного метода можно пользоваться универсальным методом decode, который сам определяет формат — METAR или TAF) эта программа напечатает следующее:
METAR for UUEE issued at 19:30 on 11st wind 080 degrees at 5m/sec visibility >10000m light snow 5-7 oktas cloud at 1100ft temperature -7C dewpoint -9C QNH 1029hPa no significant weather
(No significant weather, ха-ха.)
Точно также возможно обращаться и к отдельным параметрам, например:
say $taf->temp; # напечатало -7
say $taf->dewpoint; # -9
Этот древний модуль 1998 года вполне работоспособен и понимает разные форматы:
use v5.10;
use strict;
use Aviation::Report;
say decode_METAR_TAF($ARGV[0]);
Однако, вывод врядли будет удобым для автоматической обработки. Интересующая меня строка с температурой и точкой росы (это температура, до которой нужно охладить воздух с содержащейся в нем сейчас влагой, чтобы она начала конденсироваться) выглядит так:
temperature -7 Celsius, dew point -9 Celsius.
Это еще один модуль, который напрямую обращается за данными на сайт National Weather Service. (Помимо веб-интерфейса с GET-запросом на этом сайте можно найти отдельные файлы с погодой за каждый час суток.) Но у меня с двух попыток метод Geo::WeatherNWS не завелся.
Модуль Weather::Com — это интерфейс к API сайта weather.com.
Для пользования данными вначале необходимо получить партнерский номер и лицензионный ключ. Это открывает бесплатный доступ к API.
use v5.10;
use strict;
use Weather::Com::Finder;
my $finder = new Weather::Com::Finder({
partner_id => '1234567890',
license => 'abcdefghijklmn',
language => 'en',
});
Работа происходит в два этапа.
1. Получение списка мест
my @locations = $finder->find('Moscow, Russia');
В зависимости от точности запроса в массиве @locations окажется разное число элементов. С показанным запросом Moscow, Russia находится только одна точка (очевидно, какая), а для запроса Moscow метод find возвращает аж десять вариантов:
'Moscow, KS',
'Moscow, OH',
'Moscow, PA',
'Moscow, IA',
'Moscow, TX',
'Moscow, ID',
'Moscow, AR',
'Moscow, MI',
'Moscow, TN',
'Moscow, Russia'
2. Запрос метеоданных
На втором шаге делается собственно запрос погоды для нужного места из списка найденных (через API наверняка возможно непосредственно указать код места, однако запросы автоматически кешируются и сохраняются в файле locations.dat, который появляется на диске после первого вызова find).
say $_->current_conditions->description for @locations;
Метод description, показанный в примере к модулю, возвращает текстовую строку, например, mostly cloudy, а остальные детали возможно узнать, обращаясь к методам объектов классов Weather::Com::Location и Weather::Com::Forecast.
Фрагмент данных, которые возвращает вызов current_conditions, выглядит так:
'WEATHER' => {
'head' => {
'ur' => 'mm',
'ud' => 'km',
'form' => 'MEDIUM',
'locale' => 'en_US',
'up' => 'mb',
'ut' => 'C',
'us' => 'km/h',
'cached' => 1260478192
},
'cc' => {
'flik' => '-11',
'icon' => '26',
'lsup' => '12/10/09 11:30 PM Local Time',
'obst' => 'Moscow, RUSSIA',
'tmp' => '-5',
'wind' => {
'gust' => 'N/A',
'd' => '100',
's' => '18',
't' => 'E'
},
'hmid' => '83',
'bar' => {
'r' => '1030.1',
'd' => 'rising'
},
'moon' => {
'icon' => '24',
't' => 'Waning Crescent'
},
'dewp' => '-7',
'vis' => '10.0',
'uv' => {
'i' => '0',
't' => 'Low'
},
't' => 'Cloudy',
'cached' => 1260478192
},
'loc' => {
'suns' => '3:57 PM',
'lat' => '55.75',
'zone' => '3',
'tm' => '11:49 PM',
'sunr' => '8:48 AM',
'dnam' => 'Moscow, Russia',
'lon' => '37.62',
'id' => 'RSXX0063',
'cached' => 1260478192
},
'ver' => '2.0'
}
В числе прочего здесь содержится и информация о фазе Луны.
К сожалению, лицензионное соглашение weather.com запрещает использовать любые полученные данные (в том числе список мест) на мобильных устройствах.
На спане есть прикольный модуль Weather::Google, который умеет обращаться к API Гугла за погодой.
В документации описано много вариантов использования, но самый простой — указать населенный пункт и перечислить, какие параметры вам нужны.
use Weather::Google;
use v5.10;
use strict;
use open qw(:utf8 :std);
my $weather =
new Weather::Google('Moscow, Russia', {language => 'ru'});
my @data = $weather->current qw(
temp_c humidity wind_condition
);
say for @data;
Эта программа печатает текстовые строки с запрошенными параметрами (температура в градусах Цельсия, влажность, данные о ветре):
-3
Влажность: 89 %
Ветер: ЮВ, 1 м/с
Адрес, по которому отправляются запросы, виден в коде: www.google.com/ig/api?weather=. В принципе, ничего не мешает самостоятельно разобрать XML в ответе на прямой запрос типа http://www.google.com/ig/api?weather=Moscow, Russia.
Открылся сайт второго болгарского Perl-воркшопа, проходящего в Софии 30 января 2010 года.
Прошлогоднее мероприятие (в январе 2009-го) было одним из лучших воркшопов, которые мы вообще проводили. Было интересно и нескучно, а местные участники замечательно говорили и понимали по-английски.
Организаторы воркшопа — OpenFest и DeepText. Участие бесплатное.
Для визита в Софию гражданам России достаточно получить визу в посольстве Болгарии или визовом центре.
Строки в двойных кавычках в перле интерполируют переменные, и время от времени возникает вопрос о том, нужно ли пользоваться одинарными кавычками, если в строке нет переменных.
С одной стороны, если всегда писать двойные кавычки, то не придется судорожно отлаживать изменения, когда дописываешь к строке переменную или перевод строки, а получаешь код $var\n на выводе.
С другой стороны, одинарные кавычки спасут от опечатки (или копипейста). Сегодня я решил поправить код пятилетней давности и добавить возможность редактировать заголовок темы на форуме.
Написал «безопасный» SQL-запрос:
my $sth = $dbh->prepare("
update
thread
set
title = ?
where
$thread_id = ?
");
$sth->execute($title, $thread_id);
То, что поле в таблице называется id, а не thread_id, не важно: MySQL не сообщила об ошибке, а спокойно проинтерпретировала интерполированную строку с подставленным значением "...where 8899 = 8899", обновив все заголовки во всей таблице.
Сегодня в новом офисе Рамблера прошла 17-я встреча Moscow.pm, — по размаху превзошедшая среднего размера воркшоп.
Пришло около 40 человек, и почти четверть из этого числа были докладчиками, причем все рассказы были вовсе не блицами, а вполне полновесными выступлениями. Встреча закончилась около полуночи, и я пишу этот пост с мокрого заборчика в Александровском саду :-)
Ссылки на презентации появятся чуть позже, еще чуть более позже появятся видеозаписи, которые для нас делал Петр Федин из клуба «Бизнес в стиле .RU», наш бессменный друг после первой YAPC::Russia.
Рамблер помогает московским перл-монгерам начиная с первого воркшопа в 2007 году.
Простейший синхронный вызов методов, предоставляемых воркерами geramand, не так интересен, как асинхронный, тем более, что работа может выполняться на другой машине и на время выполнения задачи нет смысла останавливать процесс.
Gearman::Client предоставляет возможность установить обработчики, которые будут вызваны по завершении задачи (или после неудачи).
Чтобы воспользоваться этим механизмом, требуется создать набор задач (task set), и добавить в него задачу, указав адрес колбека.
#!/usr/bin/perl
use v5.10;
use strict;
use Gearman::Client;
my $client = new Gearman::Client;
$client->job_servers('example.com:4730');
my $tasks = $client->new_task_set;
$tasks->add_task(
'echo' => 10,
{
on_complete => \&completed
}
);
$tasks->wait;
sub completed {
my $result = shift;
say $$result;
}
Функция completed получает ссылку на данные, которые возвращает соответствующий воркер.
Если необходимо дождаться результата, нужно на наборе задач вызвать метод wait. Иначе колбек не будет инициирован (хотя задача и выполнится).
Через два с половиной года после первого подхода к gearmand мне захотелось (и появилась подходящая задача) попробовать его еще раз. Лучший способ вспомнить, как и что, — запустить примитивный пример.
Gearman — интересный и простой планировщик задач, серверная часть которого теперь существует и на C (а раньше была только перловая версия). Разрозненность документации (если говорить про Perl), правда, осталась на прежнем уровне. Как и необновленные ссылки на дистрибутив на основном сайте и потерянные симлинки после установки :-)
Итого. Что нужно.
1) Установить gearmand-демон (сервер).
./configure
make
make install
2) Установить модули для воркеров и клиентов.
cpan Gearman::Client
3) Запустить один или несколько серверов.
gearmand -d
4) Запустить один или несколько (например, на разных машинах) воркеров, которые подключить к единому серверу.
./worker.pl
5) Вызвать клиента и убедиться, что он работает даже когда один из воркеров не запущен.
./client.pl
При создании воркеров и клиентов нужно сразу учесть, что они ожидают номер порта. Воркер — это Gearman::Worker, а клиент — Gearman::Client, в остальном же работа с ними очень похожа.
Методу, исполняющему задачу, воркер передает аргумент типа Gearman::Job.
Воркер
Я запустил два воркера на разных компьютерах: один уменьшал полученный аргумент на единицу, а другой — увеличивал.
#!/usr/bin/perl
use v5.10;
use strict;
use Gearman::Worker;
my $worker = new Gearman::Worker;
$worker->job_servers('example.com:4730');
$worker->register_function(echo => \&echo);
$worker->work while 1;
sub echo {
my $job = shift;
say '+1';
return $job->arg + 1;
}
Клиент
#!/usr/bin/perl
use v5.10;
use strict;
use Gearman::Client;
my $client = new Gearman::Client;
$client->job_servers('example.com:4730');
for (1..10000) {
my $result_ref = $client->do_task('echo', 10);
say $$result_ref;
}
Клиенты тоже интересно запускать на двух разных компьютерах и смотреть на печать и воркеров, и клиентов (можно еще смотреть и на логи сервера geramand, но это менее впечатляюще).
XS-вариант клиента тоже попробую.