i-t-шные заметки: хитрый split
my $s = "bla bla bla";
my $count = () = split / /, $s;
Чему равен $count ?
my $s = "bla bla bla";
my $count = () = split / /, $s;
Чему равен $count ?
В последнее время на cpan'e наблюдается засилие японцев =)» UPD: и китайцев =)))
Интересно, кто в Спрингфилде программирует на Perl? Барт? Лиза? Или, может быть, Мо? Ждем появления NewNewYork.pm.
Ниже приводится перевод главы Beginning Testing из учебника Perl Testing: A Developer`s Notebook
Практические занятия в этой главе проходят через самые элементарные шаги написания и выполнения автоматизированных тестов на Perl. К концу главы вы будете знать как начать тестирование, как работают библиотеки тестирования на Perl, и где найти дополнительные библиотеки, чтобы облегчить вашу работу.
Одной из сильных сторон Perl является CPAN - архив тысяч библиотек в свободном доступе, которые решают почти любые программные задачи, включая написание и выполнение тестов. Однако прежде, чем использовать эти модули, их нужно установить. Perl упрощает эту задачу.
Лучший способ установки модулей из CPAN через систему установки модулей, которая может сама произвести поиск, загрузку сборку, установку модулей и их зависимостей.
На Unix-подобных платформах (включая Mac OS X), а также в Windows если есть в наличии С компилятор, самый простой способ установки модулей - использование модуля CPAN, который поставляется с Perl. Например, если у вас еще не установлен модуль Test::Simple, запустите командную оболочку CPAN, а затем введите install Test::Simple . Ниже приводится примерная картина установки этого модуля.
% cpan
cpan shell -- CPAN exploration and modules installation (v1.7601)
ReadLine support enabled
cpan> install Test::Simple
Running install for module Test::Simple
Running make for M/MS/MSCHWERN/Test-Simple-0.54.tar.gz
...
Appending installation info to /usr/lib/perl5/5.8.6/powerpc-linux/perllocal.pod
/usr/bin/make install UNINST=1 -- OK
Примечание: Вы также можете запустить оболочку CPAN командой perl MCPAN -e shell .
Если Test::Simple имеет какие-либо зависимости (в нашем случае их нет), оболочка обнаружит их и установит их первыми.
Если вы запускаете оболочку cpan впервый раз, возможно нужно будет указать конфигурацию системы, сети и.т.п. Обычно по умолчанию настройка производится автоматически.
В Windows чаще в всего используется дистрибутив Perl от ActiveState, в которую входит утилита ppm для загрузки, конфигурации, сборки и установки модулей. Если у вас установлен ActivePerl, откройте окно консоли и введите:
C:\>PPM
PPM> install Test-Simple
Примечание: ActivePerl также выпускает дистрибутивы Perl для Linux и Solaris, так что вышеуказанные инструкции работают и там.
Если конфигурация указана верно, ppm загрузит и установит последнюю версию Test::Simple из репозитория ActiveState.
Если модуля нет в репозитории вообще, либо его версия в репозитории не самая последняя, у вас есть несколько вариантов.
Первый вариант - вы можете найти альтернативные репозитории. Смотрите список ppm репозиториев . Ниже приводится пример подключения репозитория к PPM.
C:\>PPM
PPM> set repository dada http://dada.perl.it/PPM
PPM> set save
Если вы хотите вручную установить модуль на чистом Perl или работаете на пларформе, где имеется соответствующий компилятор, вы можете загрузить и установить модуль вручную. Найти подходящий модуль можно на сайте http://search.cpan.org. После того, как вы нашли и загрузили архив модуля, распокуйте его в домашнем каталоге:
$ tar xvzf Test-Simple-0.54.tar.gz
Test-Simple-0.54/
...
Примечание: Чтобы установить среду компиляции для Perl на Windows, обратитесь к файлу README.win32, который поставляется вместе с Perl.
Запустите программу Makefile.PL и затем выполните стандартные команды сборки и тестирования модуля:
$ perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Test::Simple
$ make
...
cp lib/Test/Builder.pm blib/lib/Test/Builder.pm
cp lib/Test/Simple.pm blib/lib/Test/Simple.pm
$ make test
Примечание: Загруженный архив имеет статус "Текущий релиз"(This Reliase), если вы планируете помочь в развитии модуля, нужно загрузить его последний релиз для разработчиков (Latest Dev Release).
Если все тесты пройдены, отлично! В противном случае, сделайте все возможное, чтобы выяснить, что не удалось сделать, почему, и насколько это поправимо. Наконец, необходимо установить модуль, запустив make install (с привилегиями администратора, если вы устанавливаете модуль в системный каталог).
Обычно Makefile.PL использует модуль ExtUtils::MakeMaker для конфигурации и установки модулей. Но иногда для этой же цели используется Build.PL и Module::Build. В этом случае нужно указать другие команды установки:
$ perl Build.PL
$ perl Build
$ perl Build test
# perl Build install
Примечание: на Unix можно использовать ./Build вместо perl Build.
В остальном, они работают практически идентично.
На Windows может потребоваться установка утилиты nmake от Microsoft для установки модулей вручную, которая использутеся так же, как и make. Таким образом, установка модулей на Windows производится командами nmake: nmake, nmake test, и nmake install.
Примечание: Файл README.win32 из исходного кода дистрибутива Perl может помочь в разрешении вопросов по утилите nmake.exe
Полезные статьи Perl по данной теме
Как я узнаю какое имя нужно указать, при установке модуля через PPM ? Я пытался установить Test-More, но утилита не может его найти!
Такое бывает когда модуль входит в состав дистрибутива модулей, поэтому нужно установить сам дистрибутив. Определить к какому дистрибутиву относится модуль можно на http://search.cpan.org. В нашем примере Test::More входит в дистрибутив Test-Simple, поэтому нужно указать в PPM название дистрибутива Тest::Simple, чтобы установился модуль Test::More.
Я не системный администратор, или я не хочу устанавливать модули в системный каталог. Как я могу установить модуль в конкретный каталог?
Укажите соответствующий параметр PREFIX при установке модуля. Например, PREFIX ~/perl/lib установит модуль в каталог ~/perl/lib (по меньшей мере, на Unix системах). Затем добавьте в переменную окружающей среды PERL5LIB путь к каталогу или не забывайте использовать прагму lib для добавления каталога в @INC во всех программах, в которых будут вызваны локально установленные модули. Примечание: Почитайте perlfaq8 чтобы узнать больше о поддержке вашего собственного каталога модулей.
Если вы устанавливаете модуль вручную, выполните Makefile.PL следующим образом:
$ perl Makefile.PL PREFIX=~/perl/lib
Примечание: MakeMaker 6.26 поддерживает INSTALLBASE, используйте его вместо PREFIX.
Если вы используете CPAN, можно настроить его для установки модулей в нужную вам директорию. Запустите оболочку CPAN под вашей учетной записью с последующим конфигурированием параметров.
% cpan
...
# указать каталог установки модулей
cpan[1]> o conf makepl_arg PREFIX=/home/UserName/mylib
# зафиксировать изменения параметров
cpan[2]> o conf commit
Если устанавливаемый модуль использует Module::Build , укажите параметр --installbase вместо PREFIX
$ perl Build.PL --installbase=~/perl
Обратитесь к документации для ExtUtils::MakeMaker, CPAN, и Module::Build за более подробной информацией.
Определился с докладами для РИТ 2010, в силу необычности перед подготовкой дождусь заключения программного комитета, с чем мне разрешат присесть на уши уважаемой аудитории, а с чем нет
Lazy::Slicely - ленивый sql join моя не-объектная read-only альтернатива ORM (DBIx::Class и прочим). 2006 года выпуска, 10 строк кода (400 байт), 10 страниц "how to" документации :), пара десятков проектов моих и друзей, чьи схемы данных описаны на базе Lazy::Slicely, и это только в рот (с) (т.е. до выкладывания на CPAN). Вообще, мой лучший велосипед, 5 лет production'а без единой модификации - можно гордиться :)
блиц-доклад: идеальная цветовая схема для редакторов кода с точки зрения восприятия цветов мозгом + ссылки на схему для популярных редакторов :)
Интерактивная модель графа на SVG+JS с автолейаутом уже писал про неё. Просто интересная (технологически) и многим полезная (легко применима для отладки) игрушка получилась
Костыли - это кошерно! доклад на тему того, что проект, эволюционно построенный как совокупность заплаток, на практике гораздо стабильнее и удобнее технически совершенных творений + немного забавных фактов из микробиологии и эволюции, намекающих на кошерность явления (соответствие идеям автора нашей уютненькой вселенной)
p.s. технические "серверные" доклады отложу на очередной HighLoad
Обнаружил в коде прекрасное:
[% FILTER replace('\n', '<br>') %][% FILTER replace('<', '\<') %][% FILTER replace('>', '\>') %][% notice.body %][% END %][% END %][% END %]
заменил на:
[% notice.body | html | html_line_break %]
Интересно, в
ru_perlfuck
примеры на Template::Toolkit принимают?
Собственно, уже не мудрствуя лукаво — кто хоть немного знает перл — разберётся.
Вконтакте добавили редиректики, что не помешает доблестному Curl через них пройти и получить куку в файл.
#!/usr/bin/perl -w
use strict;
use WWW::Curl::Easy;
use Carp;sub getURL {
my $params = shift;croak q[HASH needed as param] if ref ($params) ne 'HASH';
croak q[HREF needed in HASH] if (!exists ($params->{href}));$params->{href} = q[http://].$params->{href} if $params->{href} !~ /^http (s)?:\/\//;
my $result = 'false';
open my $oldout, «>&STDOUT» or die «Can't dup STDOUT: $!»;close STDOUT;
open STDOUT, «> /dev/null»;
my $retcode;my $curl;
{
$curl = new WWW::Curl::Easy;
$curl->setopt (CURLOPT_URL, $params->{href});
$curl->setopt (CURLOPT_USERAGENT,q[q[Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6]]);
$curl->setopt (CURLOPT_POST,1) if $params->{post};
$curl->setopt (CURLOPT_POSTFIELDS,$params->{post}) if $params->{post};
$curl->setopt (CURLOPT_COOKIEJAR, $params->{cookie_file}) if $params->{cookie_file};
$curl->setopt (CURLOPT_COOKIEFILE, $params->{cookie_file}) if $params->{cookie_file};
$curl->setopt (CURLOPT_FOLLOWLOCATION,1);
open (my $tmp_for_curl, ">", \$result);
$curl->setopt (CURLOPT_FILE,$tmp_for_curl);
$retcode = $curl->perform;
}close STDOUT;
open STDOUT, «>&», $oldout or die «Can't dup \$oldout: $!»;return {
content => $result,
retcode => $retcode,
http_code => $curl->getinfo (CURLINFO_HTTP_CODE),
effective_url => $curl->getinfo (CURLINFO_EFFECTIVE_URL),
content_type => $curl->getinfo (CURLINFO_CONTENT_TYPE)
};
}my $login = q[your@email];
my $password = q[password];
my $cookie_file = q[./cookie_file]
$login =~ s/@/%40/;
my $result = getURL ({
href => q[http://vkontakte.ru/login.php],
post => qq[op=>a_login_attempt&email=$login&pass=$password&expire=0],
cookie_file => $cookie_file
});
Должен предупредить, что это ещё одна статья, не содержащая никаких откровений. Для тех супер-гиков, которые назубок знают весь perldoc, она будет абсолютно бесполезной, так что, уважаемые супер-гики, можете проходить мимо и не информировать, что всё это есть в доках. Я и так это знаю. :-) Моя статья для всех остальных, для тех, кто весь perldoc целиком либо не осилил, либо осилил, но не понял, либо понял, но не запомнил.
Я думаю, многие знают о так называемом операторе диапазона, записывающемся как .. (две точки), с помощью которого можно быстро создавать массивы из набора последовательных элементов. Например, следующий код создаёт массив из 35 чисел: 3, 4, 5, …, 37:
my @arr = 3 .. 37;
Помимо чисел можно использовать строки: в этом случае для генерации элементов массива будет выполняться так называемый магический инкремент (например, можно задать диапазон букв: 'a' .. 'z').
Таскаю за собой по всем модулям и скриптам.
sub getURL {
my $params = shift;croak q[HASH needed as param] if ref ($params) ne 'HASH';
croak q[HREF needed in HASH] if (!exists ($params->{href}));
$params->{href} = q[http://].$params->{href} if $params->{href} !~ /^http (s)?:\/\//;
$params->{headers} = 0 if !$params->{headers};
$params->{ag} = qq ($user_agents[rand(($#user_agents+1))]) if !exists $params->{ag};
$params->{timeout} = 20 if !exists $params->{timeout};
$params->{content_length} = 600000000 if !exists $params->{content_length};my $result = 'false';
open my $oldout, «>&STDOUT» or die «Can't dup STDOUT: $!»;close STDOUT;
open STDOUT, «> /dev/null»;
my $retcode;my $curl;
{
$curl = new WWW::Curl::Easy;$curl->setopt (CURLOPT_URL, $params->{href});
$curl->setopt (CURLOPT_INTERFACE, $params->{ip}) if exists $params->{ip};
$curl->setopt (CURLOPT_CONNECTTIMEOUT,$params->{timeout});
$curl->setopt (CURLOPT_TIMEOUT,$params->{timeout});
$curl->setopt (CURLOPT_NOPROGRESS, 0);
$curl->setopt (CURLOPT_PROGRESSFUNCTION, sub {$_[2]>$params->{content_length}?1:0});
$curl->setopt (CURLOPT_USERAGENT,$params->{ag});
$curl->setopt (CURLOPT_POST,1) if $params->{post};
$curl->setopt (CURLOPT_PROXY,$params->{proxy}) if $params->{proxy};
$curl->setopt (CURLOPT_POSTFIELDS,$params->{post}) if $params->{post};
$curl->setopt (CURLOPT_HEADER,$params->{headers});
$curl->setopt (CURLOPT_COOKIE,$params->{cookie_string}) if $params->{cookie_string};
$curl->setopt (CURLOPT_COOKIEJAR, $params->{cookie_file}) if $params->{cookie_file};
$curl->setopt (CURLOPT_COOKIEFILE, $params->{cookie_file}) if $params->{cookie_file};
$curl->setopt (CURLOPT_FOLLOWLOCATION,1);
$curl->setopt (CURLOPT_REFERER,$params->{referer}) if exists $params->{referer};
open (my $tmp_for_curl, ">", \$result);
$curl->setopt (CURLOPT_FILE,$tmp_for_curl);
$retcode = $curl->perform;
}close STDOUT;
open STDOUT, «>&», $oldout or die «Can't dup \$oldout: $!»;return {
content => $result,
retcode => $retcode,
http_code => $curl->getinfo (CURLINFO_HTTP_CODE),
effective_url => $curl->getinfo (CURLINFO_EFFECTIVE_URL),
content_type => $curl->getinfo (CURLINFO_CONTENT_TYPE)
};
}
Это я такое написал? Проще уж на обычном SQL писать...
$c->stash->{'checkpoints'} = [ $c->model($MODEL)->search( { 'stgroup_id.id' => $student->stgroup_id->id, 'checkresults.student_id' => [ $student->id, undef ], }, { 'select' => [ \'me.name cpname', qw/me.id me.date max_ball/ ], 'join' => [ 'checkresults', { 'tss_id' => [ qw/stgroup_id subject_id/, { 'teacher_id' => 'user_id' } ], } ], '+columns' => [ qw/subject_id.name checkresults.ball/, qw/user_id.fname user_id.sname user_id.lname/, ], # '+as' => [ qw/subject_name ball/ ], 'order_by' => [ qw/date/ ], }, ) ];
В этом разделе собраны и сгруппированы примеры использования новых возможностей Perl 5.10, которые встречаются в модулях на CPAN.
Поскольку новые ключевые слова могут сделать программу несовместимой с предыдущими версиями компилятора, необходимо дать явные указания, чтобы активировать соответствующие фичи Perl 5.10.
Cпособы, которыми пользуются авторы, как нельзя лучше демоснтрируют принцип TIMTOWTDI:
use 5.010000; use 5.01001; use 5.010; use 5.010_000; use 5.10.0; use v5.10.0; use v5.10; use feature ':5.10';
Строки, начинающиеся с буквы v, либо содержащие две точки, называются v-string (version string или, иногда, vector string). При объявлении версии интерпретатора следущие варианты эквивалентны.
5.10.0 v5.10.0 v5.10
Обратите внимание, если при указании версии используется обычное число (с одной десятичной точкой), то следует писать не 5.10, а 5.010.
Функцию say удобно использовать во время отладки программы для вывода промежуточных значений переменных. На CPAN можно найти следы такой отладки — закомментированный вызов say.
given ($action) {
when (/^include_cmd:/) {
my $cmd = $child->content;
$cmd =~ /^include_cmd:(\s*)/;
my $ws = $1 || '';
$cmd =~ s/^include_cmd:\s*//;
#say("cmd:$ws$cmd");
$cmd = cwd() . '/' . $cmd;
@output = qx($cmd);
$child->content($ws . join($ws, @output));
}
Pod::Elemental::Transformer::Include — 08 Jan 2010
include output via files and commands
(Здесь и далее рядом с примером кода указано название модуля, откуда взят пример, дата выхода его первой версии и авторское описание; пунктуация, отступы и пробелы в коде в большинстве случаев сохранены.)
Пожалуй, самое распространенное применение оператора defined-or — установка значений по умолчанию.
В частности, удобно пользоваться вариантом с присвоением.
$port //= 5432; $host //= 'localhost';$col //= '';
Pg::Loader — 07 Jul 2008
Perl extension for loading Postgres tables
$attrz{ maxjob } //= 1;
$value //= 1;
$attrz{ $_ } //= 0;
$attrz{ verbose } //= '';
$attrz{ debug } //= '';
$val //= 1;
$exit //= 0;
$skipz->{ $job_id } //= 'Skip on SIGHUP'
Parallel::Depend — 12 Aug 2009
Parallel-dependent dispatch of perl or shell code
Чуть более сложный пример — с обращением к встроенной функции:
sub import {
shift;
my %args = @_;
# we do not care about autoviv
$^H{fixedtime} = $args{epoch_offset} //
CORE::time;
}
fixedtime — 14 Aug 2008
lexical pragma to fix the epoch offset for time related functions
Defined-or используют и непосредственно при передаче аргументов функциям.
say $answer // "I don't know enough to answer you yet.";
Hailo — 29 Jan 2010
A pluggable Markov engine analogous to MegaHAL
Следует обратить внимание, что оператор возможно использовать не только с истинными скалярами.
my $marpa_version = $Parse::Marpa::VERSION // 'undef'; my $source_version = $Parse::Marpa::Source::VERSION // 'undef';$options //= {};
Parse::Marpa — 14 Dec 2008
Generate Parsers from any BNF grammar
В следующем примере помимо многократного использования // интересно отметить, что say передается файловый дескриптор.
my $nulling_symbol = $rhs_symbol->[Parse::Marpa::Internal::Symbol::NULL_ALIAS] // $rhs_symbol;$action //= $default_action;
say {$trace_fh} 'Problems compiling action for original rule: ', Parse::Marpa::brief_original_rule($rule);
my $clone = $clone_arg // 1; my $current_parse_set = $parse_set_arg // $default_parse_set;
$choice //= 0;
$lines //= [0]; $source_options //= {};
Parse::Marpa::Internal::Evaluator — 14 Dec 2008
Generate Parsers from any BNF grammar
Наконец, и сам файловый дескриптор удобно вписывается в работу с defined-or:
my $trace_fh = $arg_trace_fh // (*STDERR);my $trace_fh = shift; $trace_fh //= *STDERR;
Parse::Marpa::Recognizer — 14 Dec 2008
Generate Parsers from any BNF grammar
Оператор defined-or часто встречается внутри вызова return, опять же чтобы вернуть определенное значение, если оно не получено на предыдущих шагах.
return $self->_get_infection( $disease->id ) // 0;my $val = $self->_get($key) // $default->{$key};
return @{ $self->_players // [] };
Games::Pandemic::City, Games::Pandemic::Config — 07 Sep 2009
Games::Risk — 18 Oct 2008
Иногда в одном из операндов // вызывают фукнции, которые могут привести к досрочному завершению программы или выходу из блока.
sub homedir {
my ($self) = @_;
require File::HomeDir;
return File::HomeDir->my_home
// croak 'File::HomeDir says you have no home
directory';
}
App::RSS2Leafnode — 02 Feb 2010
post RSS feeds to newsgroups
А вот пример, когда операндом является целый блок кода do:
sub config_filename {
my ($self) = @_;
return $self->{'config_filename'} // do {
require File::Spec;
File::Spec->catfile ($self->homedir, '.rss2leafnode.conf');
};
}
App::RSS2Leafnode — 02 Feb 2010
post RSS feeds to newsgroups
В частных случаях // действует лишь внутри части выражения, передаваемое return.
return
isodate_to_rfc822($date // $self->{'now822'});
return URI::Title::title
({ url => ($resp->request->uri // ''),
data => $resp->decoded_content
(charset => 'none')});
App::RSS2Leafnode — 02 Feb 2010
post RSS feeds to newsgroups
Весьма распространена и противоположная конструкция, когда в одном из плеч // делают попытку возврата из подпрограммы.
my $b_time = $self->item_to_timet($b_item) // return $a_item;my $a_time = $self->item_to_timet($a_item) // return $b_item;;
my $str = $self->item_to_date($item) // return;
App::RSS2Leafnode — 02 Feb 2010
post RSS feeds to newsgroups
// легко объединяется в цепочку, поэтому возможно написать конструкцию, которая делает несколько попыток присвоить defined-значение:
return (elt_to_email ($item->first_child('author'))
// elt_to_email ($item ->first_child('dc:creator'))
// elt_to_email ($item ->first_child('dc:contributor'))
// non_empty ($item->first_child_text('wiki:username'))
// elt_to_email ($channel->first_child('dc:creator'))
// elt_to_email ($channel->first_child('author'))
// elt_to_email ($channel->first_child('managingEditor'))
// elt_to_email ($channel->first_child('webMaster'))
// elt_to_email ($item ->first_child('dc:publisher'))
// elt_to_email ($channel->first_child('dc:publisher'))
// non_empty ($channel->first_child_text('title'))
# RFC822
// 'nobody@'.$self->uri_to_host
);
App::RSS2Leafnode — 02 Feb 2010
post RSS feeds to newsgroups
Возможен и подход, при котором возвращается одна-единственная переменная, которая перед этим проходит через несколько проверок с оператором defined-or:
sub item_to_language {
my ($self, $item) = @_;
my $content;
my $ret = (elt_to_language($item)
// elt_to_language($item->first_child('content')));
for (;;) {
$item = $item->parent // last;
$ret //= elt_to_language($item);
}
$ret //= $self->{'resp'}->content_language;
return $ret;
}
App::RSS2Leafnode — 02 Feb 2010
post RSS feeds to newsgroups
Объединение в цепочку нам уже встречалось, однако на нем следует задержать внимание еще раз.
my $captures = $arg {captures} // [];
my $comment = escape $arg {comment} // $name // "";
my $upgrade = $arg {utf8_upgrade} // 1;
my $downgrade = $arg {utf8_downgrade} // 1;
my $match = $arg {match} // 1;
Games::Wumpus — 24 Nov 2009
Play Hunt the Wumpus
Продолжение будет.
Те, кто использовал Gearman в работе, наверняка сталкивались с ситуацией, когда разрабатываемый воркер либо падает во время отладки, либо по забывчивости не был подключен, но при этом приложение уже начало посылать запросы на выполнение задач, обслуживаемых этим воркером.
В статусе job-сервера такие задачи видны с «перекошенным» счетчиком:
new_feature 14 0 0
То есть запросы на выполнение этой задачи в очедери уже есть, но обслужить ее некому. Непрятность здесь может быть в том, что как только подключится воркер, весь этот пул запросов потечет сразу к нему, и при отладке это крайне неудобно. Перезагружать job-сервер, чтобы обнулить счетчики, тоже не лучший выход, поскольку придется перезапустить все воркеры.
Мариан Маринов, технический архитектор компании SiteGround, сегодня добавил в интерфейс команду rmfunc, которая позволяет удалить функцию из списка зарегистрированных.
Пользоваться новой командой крайне просто:
$ telnet localhost 4730
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
status
new_feature 14 0 0
.
rmfunc new_feature
OK
status
.
Запрос на удаление функции, для которой существует «живой» воркер, завершается с ошибкой ERR there are still connected workers.
P. S. Сейчас весь код находится в отдельной ветке.
Блог изначально создавался как просто страница с советами по Perl ("Perl Tips"), но в результате вырос и потребовался новый функционал, появились желающие прокомментировать посты...
Теперь koorchik's Perl blog можно найти по адресу http://koorchik.blogspot.com/ и все желающие могут оставлять комментарии. Если у кого-то возникало желание прокомментировать старый пост, то теперь можно это сделать, поскольку весь контент был полностью перенесен.
Залил свой модуль Debug::LTrace на CPAN и смотрю у меня дефолтовая аватарка.
Начал перерывать все пункты в меню моего аккаунта на PAUSE сервере в поисках формы аплоада аватарок и все тщетно. Через 15 минут меня совсем перестал удивлять тот факт, что так мало автором на CPAN имеют свои аватарки :)).
Так вот. Решил я посмотреть в html коде откуда подгружается аватарка на CPAN и... возможно это для меня только было новоcтью :)... но это gravatar.com.
В общем решение следующее: если у меня в PAUSE юзер называется koorchik, то просто регистрирую на gravatar.com аккаунт по емейлу koorchik@cpan.org и добавляю туда свою аватарку. И все! После этого CPAN сам подхватит ее.
Несмотря на то, что проектирование интерфейсов — задача, которую програмисты не всегда решают успешно, картинка на новом сайте YAPC::Europe 2010 — великолепна.
Тема конференции — The Renaissance of Perl, проходит она в Италии, и лук в стиле записок Леонардо Ди Каприо, — прекрасен.
Да, а на ютубе (британцы говорят ючуб, кстати) есть ролик про качества перла.
Положим, у вас в шаблоне есть длинна строка, типа ......, и вы хотите её разбить между тегами. Но при этом пробелы в разрыве недопустимы. Потому просто добавте <% =%> и оно отрежет пробелы вокруг себя.
Debug::LTrace отслеживает вызов и возврат функций. Использование Debug::LTrace не требует никаких дополнительных изменений в коде. Информации о вызовах выводится через стандартный warn.
На CPAN есть и другие модули такие, как Devel::TraceCalls и Debug::Trace, но Devel::TraceCalls неудобный в использовании(хотя очень мощный), Debug::Trace - удобный и простой, но не хватает функционала.
Debug::LTrace за основу взял удобное API Debug::Trace, но дополнительно поддерживает:
TRACE C: /-FOO::out_outer() called at example.pl line 15 package FOOTRACE C: | /-FOO::outer(2,{'aaa' => {'yyy' => 'ARRAY(0x7fe610)','qqq' => 'www'}}) called at example.pl line 49 sub FOO::out_outerTRACE C: | | /-FOO::inner(3) called at example.pl line 32 sub FOO::outerTRACE C: | | | /-FOO::Dumper(3) called at example.pl line 39 sub FOO::innerTRACE R: | | | \_FOO::Dumper(3) [VOID] in 3.5e-05 secTRACE C: | | | /-FOO::inner2(3) called at example.pl line 40 sub FOO::innerTRACE R: | | | \_FOO::inner2(3) [VOID] in 1.4e-05 secTRACE R: | | \_FOO::inner(3) [VOID] in 0.000213 secTRACE C: | | /-FOO::inner2(4) called at example.pl line 33 sub FOO::outerTRACE R: | | \_FOO::inner2(4) [VOID] in 1.5e-05 secTRACE R: | \_FOO::outer(2,{'aaa' => {'yyy' => 'ARRAY(0x7fe610)','qqq' => 'www'}}) [VOID] in 0.000417 secTRACE C: | /-FOO::inner(111) called at example.pl line 50 sub FOO::out_outerTRACE C: | | /-FOO::Dumper(111) called at example.pl line 39 sub FOO::innerTRACE R: | | \_FOO::Dumper(111) [VOID] in 3.5e-05 secTRACE C: | | /-FOO::inner2(111) called at example.pl line 40 sub FOO::innerTRACE R: | | \_FOO::inner2(111) returned: (112) in 4.4e-05 secTRACE R: | \_FOO::inner(111) returned: (112) in 0.000276 secTRACE R: \_FOO::out_outer() [VOID] in 0.00088 secTRACE C: /-FOO::recurse(1) called at example.pl line 25 package FOOTRACE C: | /-FOO::recurse(2) called at example.pl line 58 sub FOO::recurseTRACE C: | | /-FOO::recurse(3) called at example.pl line 58 sub FOO::recurseTRACE C: | | | /-FOO::recurse(4) called at example.pl line 58 sub FOO::recurseTRACE C: | | | | /-FOO::recurse(5) called at example.pl line 58 sub FOO::recurseTRACE R: | | | | \_FOO::recurse(5) returned: (6) in 4.8e-05 secTRACE R: | | | \_FOO::recurse(4) returned: (6) in 0.000177 secTRACE R: | | \_FOO::recurse(3) returned: (6) in 0.00032 secTRACE R: | \_FOO::recurse(2) returned: (6) in 0.00044 secTRACE R: \_FOO::recurse(1) returned: (6) in 0.000562 secTRACE C: /-BAR::Dumper([1]) called at example.pl line 70 package BARTRACE R: \_BAR::Dumper([1]) [VOID] in 3.8e-05 sec
Конструкция
while (<filehandle>) { ... }
в перле имеет замечательную особенность: затирать глобальную переменную $_. В некоторых случаях это ведет к труднонаходимым багам. Простой пример (с фатальной ошибкой):
1 my %val = map { $_ => read_val($_) } (1,2,3);
2
3 sub read_val {
4 open my $fh, '<', 'myfile' or die $!;
5 while (<$fh>) {
6 if ($. == $_[0]) {
7 return $_
8 }
9 }
10 }
Modification of a read-only value attempted at test.pl line 5.
5.80021 2010-03-03 23:02:01 - в этой версии сделаны нужные правки. uri_for нормально понимает unicode! Всем апгрейдиться!)
5.80021 2010-03-03 23:02:01 - в этой версии сделаны нужные правки. uri_for нормально понимает unicode! Всем апгрейдиться!)
Русскоязычные студенты, изучающие и любящие Perl, присоединяйтесь к GSOC2010! Уже есть три пректа на Mojolicious perlfoundation.org
Проекты GSOC2010 perlfoundation.org
Частичный перевод документа perl5100delta.
Функция readdir() может возвращать "короткое имя" когда полное имя содержит символы, не принадлежащие кодовой таблице ANSI (ANSI codepage). Аналогично Cwd::cwd() может возвращать короткое имя директории, а glob() может возвращать короткие имена файлов и директорий. В файловой системе NTFS эти короткие имена всегда могут быть представлены в кодовой таблице ANSI. Это не будет верно для всех остальных драйверов файловых систем (file system drivers); например файловая система FAT хранит короткие имена в кодовой таблице OEM, так некоторые файлы на томах FAT остаются недоступными через ANSI API.
Кроме того, $^X, @INC, и $ENV{PATH} обрабатываются препроцессором при запуске, чтобы проверить все пути на валидность в кодовой таблице ANSI (если это возможно)
Функция Win32::GetLongPathName() теперь возвращает UTF-8 закодированное корректное имя файла вместо использования замены символов для того, чтобы подогнать имя к кодовой таблице ANSI. Новая функция Win32::GetLongPathName() может быть использована для преобразования полного имени файла в короткое, только если полное имя не пожет быть представлено в кодовой таблице ANSI.
Многие другие функции в модуле Win32 были усовершенствованы для обработки UTF-8 закодированных аргументов. Более подробно об этом в Win32.
Встроенная функция readpipe() теперь может быть переопределена. Это позволяет переопределить ее аналог - оператор qx// (также известный, как оператор `` ). Кроме того, теперь по умолчанию исползуется $_ , если не предоставлено никаких аргументов.(Rafael Garcia-Suarez)
Теперь readline() по умолчанию использует *ARGV если ему не перадано аргументов. (Rafael Garcia-Suarez)
Введен новый класс переменных. Переменные состояния (state variables) подобны лексическим переменным, но декларированные ключевым словом state вместо my. Они видны только в своей лексической области, но их значения стойкие: в отличие от лексических переменных, они не становятся неопределенными при выходе из их области видимости, но сохраняют свое прежнее значение. (Rafael Garcia-Suarez, Nicholas Clark)
Для использования 'state' переменных, нужно предварительно объявить:
use feature 'state';
или используя ключ командной строки -E .
В качестве новой формы синтаксического сахара теперь доступны операторы тестирования стека. Вы можете теперь писать f -w -x $file в ряд, что тоже самое -x $file && -w _ && -f _ . Подробнее в "-X" in perlfunc
Is Perl dead? --- isperldead.com
Здравствуйте,
Пытаюсь реализовать тайм-ауты в нитях (чтобы нить умирала/получала сигнал по истечению времени), думал сделать это через alarm(), но благодаря тому что:
Only one timer may be counting at once. Each call disables the previous timer, and an argument of 0 may be supplied to cancel the previous timer without starting a new one. (perldoc)
соотв это работает в форке, но не в нитях. Способов легально получить время выполнения нити (не засекая), чтобы отслеживать их в главной, также не нашел.
Какие существуют наиболее изящные решения этой проблемы?
Заранее благодарен за любую помощь.
P.S. Если что, про non blocking sockets я вкурсе.
Такой вопрос, если нужно получить request, ответить клиенту, но остаться в обработчике и делать что-то дальше (например, послать человека на другой сайт, но еще что-то делать, но чтоб клиент не ждал, а сразу перешел куда надо). Есть такая возможность в mod_perl? или запрос отправляется только после return ?
Да здравствует перл! Этот блог работает на перле, но писали его неизвестные мне люди Я тут зашел куда-то в админской части, и увидел массу комментариев, которые, оказывается, висят неодобренными. :-O
Часть я пооткрывал, а часть (ай!) удалил. Перл + юзабилити часто так же несовместимо, как и многие другие продукты, созданный программистами.
И еще я забыл с собой зарядное устройство от телефона.
А следующий пост будет про автобус номер один, которую начали обсуждать в комментах в прошлый раз.
Только что вернулся в гостиницу с седьмого голландского Perl-воркшопа. Он проходил в хостеле Stayok в городе Арнеме.
Это город в ста километрах от Амстердама, в часе езды электричкой (и еще полчаса от вокзала, то есть почти что московские расстояния от спальных районов до центра :-)
Как всегда, я сразу обращаю внимание на посещаемость, и даже под вечер она была около 90 % — из 39 зарегистрированных посетителей я насчитал 35.
Часть выступлений была на голланском языке (он напоминает смесь немецкого и английского с примесью французской картавости), поэтому все остальные, которые на английском, сразу стали вдвое интереснее :-)
Особенно хорош был Мартин Берендз, сделавший обзор интерпретаторов и компиляторов Perl 6, существующих в марте 2010 года. Мартин упомянул неофициальное понятие bus number, которое равно числу ведущих разработчиков проекта.
Леон Тиммерманс подкинул еще одну лингвошутку — unintentional feature (имеется в виду баг).
Через какое-то время должны появиться видеозаписи (их делали местные организаторы).

А после обеда сначала пошел мокрый снег, а потом — к вечеру — дождь; электричку пришлось ждать полчаса; и я теперь весь промокшый, но довольный :-)
Рассматриваем молодых специалистов с опытом разработки на Perl (участие хотя бы в одном проекте), знанием SQL.
Приветствуется опыт разработки по UNIX, опыт использования в работе CVS, SVN, знание Apache HTTP Server.
Условия:
* Полная занятость.
* График работы относительно гибкий (при необходимости возможно совмещать с учебой на старших курсах).
Заработная плата: 45 - 50 тыс. р. в месяц, по результату собеседования. Перспективы роста.
Офис в 5-ти минутах хотьбы от ст. м Дмитровская.
Описание работы: участие в разработке и поддержке Perl-компонентов проекта биллинга Виртуального хостинга, выполнение задач разработки серверной части сервисов и компонентов, а также клиентского GUI.
Резюме и вопросы ждем на адрес hr@agava.com.
Сегодня вашему вниманию представлена документация по модулю Lingua::RU::Inflect, позавчера вышел его второй релиз. Здесь есть приятный момент - мне не пришлось его переводить на русский язык, так как к модулю в комплекте прилагается бонус - документация на русском. Это хороший пример, того, как оформлять модули CPAN, представляющие интерес прежде всего для русскоязычного пользователя - на CPAN я пока не встречал других модулей с русскоязычной документацией.
Ниже представлена схема расположения файлов в установочном комплекте:
|~Lingua-RU-Inflect-0.02/
| |~lib/
| | `~Lingua/
| | `~RU/
| | `-Inflect.pm # <-- Модуль Lingua::RU::Inflect
| |~RU/
| | `~Lingua/
| | `~RU/
| | `-Inflect.pod # <-- Документация на русском языке
| |+t/
| |-Changes
| |-Makefile.PL
| |-MANIFEST
| |-META.yml
| `-README
А теперь, собственно, сама документация:
Lingua::RU::Inflect - Склоняет русские имена
Версия 0.02
Lingua::RU::Inflect — модуль perl, предоставляющий ряд функций для русского языка: склонение имён (а также некоторых нарицательных существительных и прилагательных), определение пола по имени, а также выбор правильной формы предлога с беглой гласной в зависимости от следующего за ним слова.
use Lingua::RU::Inflect;
my @name = qw/Петрова Любовь Степановна/;
my $gender = detect_gender_by_given_name(@name);
# $gender == FEMININE
my @genitive = inflect_given_name(GENITIVE, @name);
# $genitive == qw/Петровой Любови Степановны/;
В следующих версиях планируется склонять любые существительные, любые слова, что угодно...
Функции detect_gender_by_given_name и detect_gender_by_given_name экспортируются по умолчанию.
Кроме того, можно экспортировать константы с именами падежей:
use Lingua::RU::Inflect qw/:cases/;
Или функции и константы пола/рода:
use Lingua::RU::Inflect qw/:subs :genders/;
Или короткие псевдонимы функций
use Lingua::RU::Inflect qw/:short/;
use Lingua::RU::Inflect qw/:all/; # или
use Lingua::RU::Inflect qw/:cases :genders :subs/;
Пытается определить пол по имени. Принимает до трёх аргументов: фамилию, имя, отчество.
Возвращает MASCULINE либо FEMININE при успешном определении мужского либо женского пола соответственно или undef при невозможности однозначного определения.
При совпадении с каким-либо правилом оставшиеся правила игнорируются.
Отчество, если указано, позволяет однозначно определить пол: женские отчества заканчиваются на «на», мужские — на «ич» и «ыч».
Большинство русских женских имён оканчивается гласными «а» и «я». Большинство русских мужских имён оканчивается согласной.
Существуют исключения из обоих правил, женские имена (например, русское имя Любовь, библейские имена Руфь, Рахиль, иностранные имена) могут заканчиваться согласной буквой; мужские имена могут заканчиваться на «а» и «я», особенно это относится к уменьшительно-ласкательным формам имён: Алёша (Алексей), Коля (Николай) и т. д. По некоторым уменьшительно-ласкательным формам имён нельзя установить пол ввиду неоднозначности: так, имя Саша соответствует как мужскому имени Александр, так и женскому Александра; Женя — мужскому Евгений и женскому Евгения. Подобные исключения обрабатываются.
При получении неопределённого результата функция пытается определить его на следующем шаге.
Большинство русских фамилий образовано от притяжательных слов (включая имена). Женские варианты таких фамилий заканчиваются на «а». Некоторые фамиллии образованы от прилагательных. Женские варианты таких фамилий заканчиваются на «я».
Склоняет фамилию, имя, отчество. Принимает до 5 аргументов — пол, падеж, фамилия, имя, отчество (фамилия, имя, отчество должны быть в именительном падеже).
Возвращает список — фамилию, имя, отчество в заданном падеже.
Определяет пол по имени и склоняет это имя.
Принимает до 5 аргументов — падеж, фамилия, имя, отчество (фамилия, имя, отчество должны быть в именительном падеже).
Падеж может быть представлен константой, доступны имена: NOMINATIVE , GENITIVE , DATIVE , ACCUSATIVE , INSTRUMENTAL , PREPOSITIONAL для именительного, родительного, дательного, винительного, творительного и предложного падежей соответственно.
Возвращает список — фамилию, имя, отчество в заданном падеже.
Выбирает предлог с беглой гласной (например, о/об/обо) по следующему за ним слову.
Принимает 2 аргумента: предлог и следующее_слово. В качестве предлога выступает строка с наиболее коротким из возможных значений. Допустимые предлоги: 'в' , 'из' , 'к' , 'над' , 'о' , 'от' , 'пред' , 'перед' , 'под' и 'с' .
Для вызова функции с допустимыми предлогами задан ряд псевдонимов. Имена псевдонимов образованы от полных вариантов (чтобы избежать использования однобуквенных идентификаторов) за исключением ob :
izo — псевдоним для choose_preposition_by_next_word 'из',
ko — псевдоним для choose_preposition_by_next_word 'к',
nado — псевдоним для choose_preposition_by_next_word 'над',
ob — псевдоним для choose_preposition_by_next_word 'о',
oto — псевдоним для choose_preposition_by_next_word 'от',
podo — псевдоним для choose_preposition_by_next_word 'под',
predo — псевдоним для choose_preposition_by_next_word 'пред',
peredo — псевдоним для choose_preposition_by_next_word 'перед',
so — псевдоним для choose_preposition_by_next_word 'с',
vo — псевдоним для choose_preposition_by_next_word 'в',
По умолчанию эти псевдонимы не экспортируются. Можно указать экспортирование явно, указав имена нужных функций либо тэги :short и :all .
Пример использования псевдонимов:
use Lingua::RU::Inflect qw/:short/;
map {
print ob, $_;
} qw(
арбузе баране всём Елене ёлке игле йоде
мне многом огне паре ухе юге яблоке
);
map {
print so, $_;
} qw(
огнём водой
зарёй зноем зрением зябликом
садом светом слоном спичками ссылкой
Стёпой стаканом сухарём сэром топором
жарой жбаном жратвой жуком
шаром шкафом шлангом шубой
);
Пожалуйста, присылайте сообщения о найденных неполадках и желаемых возможностях на bug-lingua-ru-inflect at rt.cpan.org , или через веб-интерфейс на http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Lingua-RU-Inflect. Меня известят, и вы будете автоматически оповещены при устранении найденных вами неполадок.
Вы можете найти документацию к этому модулю с помошью команды perldoc.
perldoc Lingua::RU::Inflect
Кроме того, вы можете найти информацию в других местах:
http://www.imena.org/declension.html
Александр Сапожников http://shoorick.ru/
Эта библиотека является свободным программным обеспечением, вы можете распространять и модифицировать её на тех же условиях, что и Perl.
Perl 5.10 увидел свет в 20 день рождения языка — 18 декабря 2007 года. Уже прошло более двух лет, и за это время успели появиться девелоперские версии 5.11.0, 5.11.1, 5.11.2, 5.11.3 и 5.11.4, и вот-вот появится версия 5.12, предназначенная для использования в реальных приложениях.
Perl 5.10 представил много нововведений, и сегодня интересно посмотреть, как часто они используются авторами модулей CPAN — модулей, появившихся после релиза 5.10, либо обновленных с того времени.
На CPAN сейчас хранится около 80 000 модулей в 20 000 дистрибутивах, список авторов содержит около 8000 имен. Как часто здесь используются фичи Perl 5.10?
Ответ: новые фичи встречаются в двух сотнях модулей, созданных сотней авторов.
Кратко о том, что появилось в Perl 5.10.
— Встроенная функция say, которая работает аналогично print, но добавляет перевод строки.
— Оператор сопоставления (смартматчинга) ~~ сопоставляет свои аргументы согласно здравому смыслу (и, разумеется, четким правилам, описанным в документации). Например, в этих примерах аргументы имеют разный тип, но используется один и тот же оператор.
$a ~~ /\d/$a ~~ @list
@list ~~ %hash
— Составной оператор выбора под условным названием switch. С помощью новых ключевых слов given, when и default возможно создать условную конструкцию, аналогичную switch/case в C и других языках. Важное отличие в том, что внутри given происходит не простое сравнение, а сопоставление (или смартматчинг).
given($x) {
when(/a/) {...}
when('b') {...}
default {...}
}
— Модификатор state позволяет создавать лексические переменные, сохраняющие значение между вызовами подпрограммы. Использование state похоже на объявление автоматической переменной со словом static в C.
sub counter {
state $c = 0;
return ++$c;
}
— Новшества в регулярных выражениях. Регулярные выражения существенно переработаны, в частности, добавлены именованные сохраняющие скобки. В этой статье про регулярные выражение почти не упоминается, поскольку они достойны отдельного рассказа.
(?<name>) \K \R %+ %- \g<name>
— Бинарный оператор defined-or (//). Возвращает первый из аргументов, который содержит определенное (не undef) значение. Может использоваться и в варианте с присвоением.
Следующие два примера иллюстрируют логику, которая часто прослеживается в сообщениях о вакансиях.
$city = $arg // 'Moscow';$vacancy{city} //= 'Moscow';
Продолжение будет.
Имеется сверхбольшой XML документ вида:
<?xml version="1.0" encoding="utf-8"?>
<envelope>
<head>
<title>Whatever what</title>
...
</head>
<body>
...
<item>Item1</item>
<item>Item2</item>
...
<item>ItemN</item>
</body>
</envelope>
#!/usr/local/bin/perl use strict;my ($filename, $max_items) = ("test.xml", 1);
local $/ = "</item>";
open(my $fh, "<:utf8", $filename) || die qq/Cannot open $filename for reading: $!/; my $last_str; $. > $max_items ? ($last_str = $_) : print while <$fh>;
print $last_str if defined($last_str);
# Perl is supposed to close $fh for us.
Lingua::RU::Inflect 0.02:
pod2html ругается, что не знает слова =encoding, а в man-страницах кириллица пропадает вовсе.choose_prepositions_by_next_word для выбора предлога с беглой гласной по следующему за ним словом, а также куча коротких имён для вызова этой функции с разными предлогами: izo, ob, so и т. п.
На основе записей в трудовой книжке.
1999, Москва
— Я программирую на Perl. Особенность в том, одно и то же действие можно записать по-разному. Это и непривычно, и немного сложно, но интересно.
Это сказал мой товарищ, который в то время делал сайт одного из поставщика радиодеталей. Я же в то время писал на C++ программы для обработки данных физических экспериментов по сталкиванию частиц, делал статистический анализ данных, замаскированных шумом, и пытался применять новейшие математические приемы — вейвлеты — для анализа электрокардиограмм.
В книжных магазинах моего родного города я давно видел несколько книг с большими буквами PERL. Неосознанно я хотел узнать, что это, но тогда буквы значили не больше, чем аббревиатура VRML. Не хочу сказать, что произнесенные между делом слова товарища повлияли на мой выбор, но и отрицать этого не стану.
2000—2010, Москва
С этого года Perl стал меня кормить. За десять лет я совершенствовал себя и свои знания в журнале «Радио», фонде научных исследований «Прагматика культуры», студии Артемия Лебедева (да-да, там я тоже делал некоторые вещи на перле), российском информационном агентстве «РИА Новости», компании Q1 и в ООО «Гностик».
2010, Амстердам
В марте я подписал контракт с компанией Booking.com — еще одним лидером интернетов, который знает толк в перле и где не стыдно работать.
Ниже приводится вольный перевод раздела 'Overview' из книги "Perl Testing A Developer's Notebook"
Есть ли в разработке программного обеспечения тема сексуальнее, чем тема о тестировании программного обеспечения? Что это кроме программирования игр, 3D графики, аудио, высокопроизводительных кластеров, хороших сайтов и.т.д ? Во всяком случае, тестирование находится ниже этого списка. И это прискорбно, потому что хорошее тестирование может увеличить производительность, улучшить дизайн, поднять качество, облегчить накладные расходы, и помочь удовлетворить ваших клиентов, сотрудников и менеджеров.
Perl имеет большую историю автоматизированных тестов. Еще до релиза Perl 1.0 включал всеобъемлющий набор тестов, и это пошло ему на пользу. Изучение того, как работает Perl инструментарий тестирования может в целом сделать вас лучшим программистом, так как Perl инструментарий тестирования поможет в решении любых задач тестирования, которые могут у вас возникнуть, даже в других языках программирования.
Как и все книги из серии Записная книжка O'Reilly', эта книга пропускает скучную прозу и сосредотачивает внимание на серии упражнений, которые показывают практические примеры реализации задач.
"Записная книжка разработчика: Perl тестирование" поможет быть в теме и:
Создавать базовые тесты Perl с легкостью и интерпретацией результатов
Применять специальные методы и модули для улучшения ваших тестов
Включать наборы тестов в ваши проекты
Тестировать базы данных и их данные
Тестировать веб сайты и веб проекты
Использовать единый формат вывода результатов тестирования(Test Anything Protocol/TAP) с тестами проектов, написанных на других языках
С сегодняшней увеличенной рабочей нагрузкой и короткими циклами развития, модульное тестирование более жизненно необходимо для построения надежных, высококачественных программ, чем когда-либо прежде. Однажды освоеные, эти уроки помогут вам обеспечить корректность низкоуровневого кода, сократить цикл разработки программного обеспечения и упростить его обслуживание.
Вы не должны быть вольным крепким орешком и разработчиком программ с отрытым исходным кодом, который живет, дышит и мечтает Perlом для использования этой книги. У вас просто должно быть желание делать свою работу немного лучше.
Из 49 ответов на вопрос «@var — это массив или список?», оставшихся после отсеивания накруток сторонников массивов, сложилась такая картина общественного мнения:

Себастьян Виллинг затронул в своем блоге вечную тему о том, как отрезать от строки пробелы с обеих сторон, сделав это в одно действие.
Вместо двух замен
$str =~ s/^\s+//;
$str =~ s/\s+$//;
Себастьян указывает на такой вариант:
$str =~ s/^\s*(.*?)\s*$/$1/;
Интересно почитать и комментарии, где предлагают несколько похожих вариантов с альтернативами в регулярном выражении:
$str =~ s/(^\s+|\s+$)//g;
$str =~ s/(?:^\s+|\s+$)//g;
$str =~ s/^\s*|\s*$//g;
$str =~ s/^\s+|\s+$//g;
P. S. В комментариях, кстати, видно, как почти одно и то же выражение разные люди записывают по-разному.
Планирую участие на конференции
oleg_bunin
РИТ++
До сих пор участвовал только в конференциях Олега, впечатления самые положительные. Первый раз участвовал 3 года назад, в апреле 2007 года, РИТ 2007, это была моя первая конференция, новый для меня опыт, сразу с 3 докладами:
Архитектура рекламной сети "КиноМедиа" - самый первый доклад, о моём первом большом специфическом проекте
Поисковый спам - устроил небольшое шоу "я - спамер" :)
Практическое применение XSLT в рамках REST - помечтал о технологиях
Затем осенью удачно выступил на HighLoad 2007 с докладами:
Высоконагруженные приложения как совокупность веб-сервисов
Сетевая многозадачность: событийные машины
на РИТ 2008 был в качестве гостя с братом
scarych
, на HL++ 2008 был с докладом
Архитектурные приемы: онлайн-игры
К сожалению, по личным обстоятельствам пропустил РИТ 2009 и hl++ 2009.
На предстоящем РИТ 2010 хочу сделать
совместный доклад в секции MayPerl с моим коллегой по "Точке Кипения" и другом
sharifulin
забавный блиц-доклад в общей секции РИТ
полноценный доклад в общей секции РИТ (возможно, если сформулирую достойную тему)
Обновил профиль:
Технический руководитель игры dozory.ru, поисковый спамер ("black seo"), большой любитель perl и сетевого программирования.
ВНИМАНИЕ, СПОЙЛЕР :) Также впервые серьёзно задумался о том, чтобы выложить свою закрытую разработку, которой плотно занимаюсь последние 2 года (мой собственный компактный pure perl асинхронный сетевой мультиплексор, альтернатива POE/AnyEvent/...)
Если сделаю это, пожалуй, выберусь с Шитовым и Шарифулиным на очередную международную YAPC с презентацией, оно того стоит.
До встречи на РИТ!
Задумался, делать ли в Lingua::RU::Inflect проверку наличия элемента в списке циклом (который работает везде) или же взять появившийся в 5.10 оператор ~~.
Вроде бы, с одной стороны, требовать от юзера апгрейдить перл только лишь из-за того, что мне лень писать цикл — нехорошо. Более того, заставлять апгрейдиться на живом сервере (а потом ещё надо будет perl-after-upgrade делать, что тоже потребует какого-то времени) — совсем никуда не годится.
С другой стороны, компактный код, при том, что пишется быстрее, ещё и понятнее выглядит.
P. S. В /var/db/pkg/perl-5.10.1/+REQUIRED_BY обнаружил строку bsdpan-Lingua-RU-Inflect-0.01 — откуда она там? В /var/db/pkg/perl-5.8.9_3/+REQUIRED_BY её нет. И вообще, откуда у меня вдруг два параллельных перла-то взялось? Я, вроде, версию 5.10 специально не ставил...
upd/17:40: Снёс 5.8, оставил только 5.10. Но вот как провернуть безболезненный апгрейд на сервере? Что-то я опасаюсь ненулевого даунтайма. А, возможно, и на час он может растянуться, что плохо.
* thanks to optimizations from chromatic, Jonathan, and Vasily, Rakudo has a lot of speed improvements
* in particular, it can run those tests in under 10 minutes, non-parallel, depending on your hardware
* older releases took 25 minutes and more
Модуль XML::Parser::Expat создавался в те далекие времена, когда XML файлы длиннее 2Gb не могли присниться даже в самом страшном сне любому относительно-нормальному человеку. Но времена изменились, и теперь многогигабайтные XML-файлы - не редкость. А между тем, метод XML::Parser::Expat::current_byte() по-прежнему возвращает число типа long вместо long long.
При этом, в очередной раз поражает инертность Perl-сообщества. Вместо того, чтобы просто взять и подправить Expat.xs надлежащим образом, взволнованные пользователи пишут: "... this is not an issue when using a 64 bit version of perl.". Кстати говоря, впервые проблема была озвучена не менее 4-х лет назад. А в RT открытыми остаются по меньшей мере три! примерно одинаковых баг-рипорта.
На прошлом уроке, мы установили Perl и наиболее подходящий редактор исходного кода. Начинается самое интересное! Сегодня мы установим Mojo, рассмотрим основы работы с ним и напишем «Hello World!». Прежде чем переходить к установке, посмотрим, что же такое Mojo вообще и для чего он нужен. Mojo — не просто фреймворк, как например Codeigniter или Kohana для PHP. Mojo — это набор библиотек, для создания своего фреймворка, т.е. фреймворк для фреймворка (как-бы странно это не звучало). В стандартную поставку Mojo входит два «готовых» фреймворка, которые можно использовать для написания приложения/сайта — Mojolicious и Mojolicious::Lite. C первым из них мы и будем сегодня знакомиться.
mroДобавлена новая прагма, mro ( для порядка разрешения метода(Method Resolution Order )). Это позволяет переключаться на базовый класс (per-class basis), алгоритм, который perl использует для поиска унаследованных методов в иерархии множественного наследования. По умолчанию MRO не изменен ( Поиск в глубину (DFS, Depth First Search ). Другой MRO имеется в наличии: C3 алгоритм. Смотрите mro для получения более подробной информации (Brandon Black)
Отметим, что в связи с изменениями в осуществлении поиска иерархии класса, код, который используется для присвоения *ISA неопределенного значения скорее всего будет прерван. Во всяком случае, присвоение неопределенного значения *ISA имел побочный эффект удаления магического массива @ISA а это не должно было происходить. Также, кэш *::ISA::CACHE:: больше не существует, чтобы заставить сбросить кэш @ISA, теперь нужно использовать mro API, или же просто осуществить присвоение массиву @ISA (например @ISA = @ISA ).
Увидел сегодня на UWDC ещё один метод быстрого создания презентаций — свердловчане Антон Халиков и Роман Иманкулов использовали в своих докладах S5: A Simple Standards-Based Slide Show System — систему, где презентация хранится в HTML-файле. S5, в отличие от takahashi, работает (вроде бы) в разных браузерах (а не только в файрфоксе < 3.6) — у меня оно успешно заработало в Google Chrome. Достигается это за счёт использования не специфического для мозиллы XUL-файла, описывающего интерфейс, а обычного HTML: синтаксис самого описания презентации получается более сложным по сравнению с простым текстовым описанием, применяемым в takahashi, но тому, кто знает HTML, это не страшно. Внешний вид, вроде, можно выбирать из готовых тем, а можно и перекрасить всё вручную правкой CSS-файла.
В качестве тренировки слепил коротенькую презентацию о Lingua::RU::Inflect — можно делать блиц-доклад? :-)
Вчера перенёс свеженаписанные функции выбора предлога в модуль, добавил к ним пару не экспортируемых по умолчанию синонимов — ob и so, сделал тесты, подправил модуль, чтобы проходил новые тесты — да призадумался: а что, если изменяющихся предлогов больше? Не писать же свою функцию на каждый, надо бы оптимизировать процесс. Сегодня, по пути на UWDC попробовал вспомнить, что же есть в русском языке: насчитал кучу групп: в/во, к/ко, из/изо, над/надо, о/об/обо, перед/передо/пред/предо, под/подо, с/со — и вполне возможно, что это ещё не всё. Надо будет Дитмара нашего Эльяшевича почитать, проверить свои познания в области русского языка. Посему релиз версии 0.02 откладывается на время чтения Розенталя и придумывания универсальной функции выбора предлога.
P. S. Технические доклады на UWDC — интересны, докладчики молодцы. То, что я слышал из других областей (про CRM и «Как стать популярным блоггером») — какая-то невнятная вата.
Написал небольшой скрипт рассылки по фейсбуку [!] На данный момент шлет только по друзьям [+] Многопоточность [+] Антикапча [+] Ротация сообщений [+] Автообновление Настройка скрипта производится в файле config.cfg. Скрипт практически не тестировался. Обо всех ошибках и пожеланиях просьба сообщать в комментариях. P.S. Если используете аккаунты, не подтвержденные по смс, то будет много капчи. Скрипт: скачать Также рекомендую почитать: Чекер одноклассников (5) Услуги (7) Спаммер смс (МТС) (8) Спаммер [...]
Как вы называете в повседневном обиходе переменную с именем @var? Массивом или списком?
Продолжаю баловаться двумя языками — перлом и русским:
Наверное, добавлю эти функции в Lingua::RU::Inflect — и можно будет сегодня-завтра выложить версию 0.02.#!/usr/bin/perl -wl -CSuse strict; use utf8;
$,=' ';
sub choose_preposition_about_by_next_word { return /^[аиоуыэ]/i ? 'об' : 'о'; }
sub choose_preposition_with_by_next_word { return /^с[^аеёиоуыэюя]/i ? 'со' : 'с'; }
map { print choose_preposition_about_by_next_word, $_; } qw( арбузе баране Елене ёлке игле йоде огне паре ухе юге яблоке );
map { print choose_preposition_with_by_next_word, $_; } qw( огнём садом светом слоном спичками ссылкой Стёпой стаканом сухарём сэром топором );
Нашел очень хороший сервис по Perl perl5doc.ru Это добавок к beshenov.ru и perlrussia.ru