Хитрый момент во множественном наследовании

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

Простой пример. Имеется два модуля BaseA и BaseB, содержащие только метод import.

package BaseA;

sub import {
    print "Base A\n";
}

1;


package BaseB;

sub import {
    print "Base B\n";
}

1;

Модуль Derived содержит лишь инструкции, указывающие эти два класса как базовые:

package Derived;

use base BaseA;
use base BaseB;

1;

Что произойдет, если в программе используется модуль Derived, и вызван метод import?

use Derived;

Derived->import();

На печать дважды выводится строка Base A (первый раз при подключении, второй — при явном вызове import).

А вот если поменять порядок наследования внутри Derived:

package Derived;

use base BaseB;
use base BaseA;

1;

то на печать дважды выводится Base B.

Perl, Пърл, पर्ल

Мне стало интересно, как выглядит название языка Perl на языках, не использущих латинский алфавит.

На википедии нашлось более десятка вариантов названия:

Арабский — يرلبيرل
Болгарский — Пърл
Грузинский — პერლი
Гуджарати — પર્લ
Иврит — פרל
Корейский — 펄
Персидский — پەرل
Сербский — Перл
Тайский — เพิร์ล
Тамильский — பெர்ள்
Фарси — پرل
Хинди — पर्ल
Японский — パール

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

Планы на 2010 материализуются

В списке сайтов конференций, построенных на платформе Act, появилось первое мероприятие на 2010 год.

Это второй болгарский Perl-воркшоп «BG Perl — 2», который состоится в Софии в конце января или начале февраля.

Предыдущий воркшоп 31 января 2009 года собрал около 40 человек, и помещение оказалось немного тесным. Как организатор могу сказать, что это мероприятие я считаю одним из лучших, которые мы сделали. Кстати, в очередной раз замечу, что участники весьма хорошо общались по-английски. Все выступления, за исключением вступительного слова, были на английском языке.

Недавно к соревнованию Iron Man присоединился один из участников воркшопа, Петар Шангов, который открыл блог mechanicalrevolution.com. (На фотографии видны сложенные руки Петара — он крайний справа за передним рядом столов.)

Верблюды

В рассылке Лондон.pm активно обсуждаются плюшевые верблюды, их стоимость и где приобрести.

Где бы вы ни встретили Лиона Брокарда (на фото справа), всегда увидете с ним маленького плюшевого верблюда, которого Лион постоянно привозит на все мероприятия.

Верблюда зовут Амелия и он является официальным верблюдом London.pm.

Обсуждение, впрочем, перешло от ссылок на Амазон к проблеме отстрела верблюдов в Австралии, а затем и к блюдам из верблюжатины.

Inline::CPP

Inline::CPP — замечательный инструмент для того, чтобы с легкостью собирать вместе компоненты, написанные на C++ и Perl.

Не то, чтобы мне потребовалось радикально оптимизировать программу, переписав критические куски на C++. Мне просто захотелось сделать на этом языке часть проекта, написанного на Perl. Мне потребовался грамматический парсер, который легко удалось написать, используя библиотеку Spirit из комплекта Boost.

Что у нас есть для вызова функции из программы на Perl? У нас есть XS, но он в оригинале пригоден для связки с C, а не C++. Даунгрейдить программу ради промежуточного инструмента — не выход. В любом случае писать приходится на синтетическом языке (я пробовал).

Существуют несколько рецептов того, как используя XS подключить фрагменты программы на C++. Но даже те методы, которые аккуратно и доступно изложены, неадекватно сложны для вызова calc(«2+2»). Например, по одному из старых рецептов требуется выполнить с десяток шагов, найти специальный файл perlobject.map, а в каталоге с проектом возникает месиво из файлов:

blib        lib          MANIFEST      MyPackage.o    perlobject.map    ppport.h  typemap
Changes     Makefile     MyPackage.bs  MyPackage.xs   perl-xs-c++.html  README
_howto.txt  Makefile.PL  MyPackage.c   MyPackage.xsc  pm_to_blib        t

Мой выбор — Inline::CPP. Вся программа сводится к подключению этого модуля и вызову нужной функции:

use Modern::Perl;
use Inline 'CPP' => "./calc.cpp";

say calc($ARGV[0]);

Магия компиляции и сборки остается за горизонтом; единственное видимое проявление — каталог _Inline в рабочей директории (но и его можно перенести в /tmp или куда угодно). И, разумеется, замедление первой загрузки программы. При повторных запусках задержек нет, потому что используются готовые .so-библиотеки.

Замечательно, что C++-файл остается C++-программой: никаких дополнительных инструкций не требуется. Еще более важно, что такая программа, не будучи специально предназначенной для работы с перлом, может быть частью обычной программы на C++. Например, функцию можно вызвать для тестирования:

#include<iostream>

using namespace std;
double calc(char*);

int main() {
    cout << calc("1+2*3") << "\n";
}

У Inline::CPP пара мелких недостатков (которые, в прочем, никак не омрачают впечатление, удобство и пользу модуля). Во-первых, вывод сообщений об ошибках, который в моем случае по умолчанию попадал в логи Апача, оказывается месивом из строк и литерализированных переводов строк. Вместе с сообщением о самой ошибке (а в C++, когда используешь шаблонные классы, легко получить многостраничное сообщение даже при небольшой ошибке) сюда же попадает командная строка, с которой вызывался компилятор C++:

/usr/bin/perl /usr/share/perl/5.10/ExtUtils/xsubpp  -typemap /usr/share/perl/5.10/ExtUtils/typemap   Calculator_f4e3.xs > Calculator_f4e3.xsc && mv Calculator_f4e3.xsc Calculator_f4e3.c\ng++ -c   -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g   -DVERSION=\\"0.00\\" -DXS_VERSION=\\"0.00\\" -fPIC "-I/usr/lib/perl/5.10/CORE"   Calculator_f4e3.c\nIn file included from Calculator_f4e3.xs:15:\n/usr/include/boost/spirit/core.hpp:18:4: warning: #warning "This header is deprecated. Please use: boost/spirit/include/classic_core.hpp"\nCalculator_f4e3.xs: In function 'double eval_expr()':\nCalculator_f4e3.xs:154: error: 'info' was not declared in this scope\nCalculator_f4e3.xs: In function 'double calc(const char*)':\nCalculator_f4e3.xs:190: error: 'exal_expr' was not declared in this scope\nCalculator_f4e3.c: In function 'void boot_WHL__Parser__Calculator_f4e3(PerlInterpreter*, CV*)':\nCalculator_f4e3.c:354: warning: deprecated conversion from string constant to 'char*'\nmake: *** [Calculator_f4e3.o] Error 1\n\nA problem was encountered while attempting to compile and install your Inline\nCPP code. The command that failed was:\n  make > out.make 2>&1\n\nThe build directory was:\n/_Inline/build/WHL/Parser/Calculator_f4e3\n\nTo debug the problem, cd to the build directory, and inspect the output files.\n\n at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser/Calculator.pm line 6\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser/Calculator.pm line 6.\nCompilation failed in require at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser.pm line 21.\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser.pm line 21.\nCompilation failed in require at /home/ash/infolavka/trunk/whoyougle/lib/Infolavka/Default/Worker.pm line 10.\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/Infolavka/Default/Worker.pm line 10.\nCompilation failed in require at (eval 39) line 3.\n\t...propagated at /usr/share/perl/5.10/base.pm line 92.\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/Tinyurl/Worker.pm line 12.\nCompilation failed in require at /usr/local/apache2-dev/conf/vhosts/ash.dev line 480.\nBEGIN failed--compilation aborted\t(in cleanup) /usr/bin/perl /usr/share/perl/5.10/ExtUtils/xsubpp  -typemap /usr/share/perl/5.10/ExtUtils/typemap   Calculator_f4e3.xs > Calculator_f4e3.xsc && mv Calculator_f4e3.xsc Calculator_f4e3.c\ng++ -c   -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g   -DVERSION=\\"0.00\\" -DXS_VERSION=\\"0.00\\" -fPIC "-I/usr/lib/perl/5.10/CORE"   Calculator_f4e3.c\nIn file included from Calculator_f4e3.xs:15:\n/usr/include/boost/spirit/core.hpp:18:4: warning: #warning "This header is deprecated. Please use: boost/spirit/include/classic_core.hpp"\nCalculator_f4e3.xs: In function 'double eval_expr()':\nCalculator_f4e3.xs:154: error: 'info' was not declared in this scope\nCalculator_f4e3.xs: In function 'double calc(const char*)':\nCalculator_f4e3.xs:190: error: 'exal_expr' was not declared in this scope\nCalculator_f4e3.c: In function 'void boot_WHL__Parser__Calculator_f4e3(PerlInterpreter*, CV*)':\nCalculator_f4e3.c:354: warning: deprecated conversion from string constant to 'char*'\nmake: *** [Calculator_f4e3.o] Error 1\n\nA problem was encountered while attempting to compile and install your Inline\nCPP code. The command that failed was:\n  make > out.make 2>&1\n\nThe build directory was:\n/_Inline/build/WHL/Parser/Calculator_f4e3\n\nTo debug the problem, cd to the build directory, and inspect the output files.\n\n at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser/Calculator.pm line 6\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser/Calculator.pm line 6.\nCompilation failed in require at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser.pm line 21.\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/WHL/Parser.pm line 21.\nCompilation failed in require at /home/ash/infolavka/trunk/whoyougle/lib/Infolavka/Default/Worker.pm line 10.\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/Infolavka/Default/Worker.pm line 10.\nCompilation failed in require at (eval 39) line 3.\n\t...propagated at /usr/share/perl/5.10/base.pm line 92.\nBEGIN failed--compilation aborted at /home/ash/infolavka/trunk/whoyougle/lib/Tinyurl/Worker.pm line 12.\nCompilation failed in require at /usr/local/apache2-dev/conf/vhosts/ash.dev line 480.\nBEGIN failed--compilation aborted at /usr/local/apache2-dev/conf/vhosts/ash.dev line 480.\n

Во-вторых, из документации не сразу понимаешь, как обеспечить прозрачную компиляцию, когда хочется компилировать внешний файл (а не писать код прямо в Perl-файле после __DATA__). А поскольку мне нужен вывод через поток iostream из стандартной библиотеки STL, приходится конфигурировать Inline::CPP для его поддержки. Несколько впадаешь в ступор, когда понимаешь, что одновременно эти пожелания выполнить не получится. Вместо этого, оказывается, нужно записать use Inline::CPP дважды:

use Modern::Perl; use utf8; use Inline 'CPP' => Config => ENABLE => 'STD_IOSTREAM', DIRECTORY => '/tmp'; use Inline 'CPP' => "$ENV{PROJECT_ROOT}/lib/WHL/Parser/calculator.cpp";

Резюме: пользуйтесь Inline::CPP, это облегчит жизнь.

Белорусский Perl-воркшоп

17 октября 2009 года в Минске пройдет второй белорусский Perl-воркшоп «BY Perl».

Мероприятие бесплатное, для участия необходимо зарегистрироваться на сайте 2009.perlbelarus.org. Место проведения будет объявлено позже.

Организаторы (Minsk.pm и Moscow.pm) приглашают докладчиков выступить на воркшопе.

Исходные коды perldoc.perl.org

Опубликованы исходники сайта perldoc.perl.org.

Джон Аллен (Jon Allen, JJ) — создатель сайта perldoc.perl.org — открыл исходные коды сайта. Они доступны на Гитхабе.

Perldoc.perl.org представляет собой онлайновую версию документации по Perl. Сайт содержит все материалы, входящие в дистрибутив языка. Сейчас доступна документация версий 5.10, 5.8.9 и 5.8.8, однако автор сайта планирует расширить набор как минимум до версии 5.8.

Чуть меньше месяца назад perldoc.perl.org поменял дизайн. Предыдущая версия выглядела примерно так, как сейчас выглядит еще один сайт — с переводами документации на другие языки — perldoc.org.

Почему важны слайды и видеозаписи

Организаторы каждого мероприятия — воркшопа или конференции — должны заботиться о том, чтобы доклады были сохранены для истории.

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

Например, недавнюю YAPC::Europe в Лиссабоне посетило около 330 человек. При этом по статистике 2007 года известно по крайней мере о 4580 Perl-программистах в мире (знакомых с английским языком). Большинство из них не были на конференции и никогда не увидят ни слайдов, ни видезаписей.

Реально программистов в несколько раз больше: нужно учесть тех, кто не смог принять участия в опросе perlsurvey.org из-за незнания английского, либо просто не захотел, либо вообще не знал.

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

Мероприятия в восточной части Европы до конца года

До конца текущего года состоятся несколько Perl-мероприятий в восточной части Европы.

Во-первых, на 17 октября планируется второй белорусский Perl-воркшоп в Минске.

Во-вторых, на начало декабря готовится второй воркшоп TwinCity — совместное мероприятие Vienna.pm и Bratislava.pm.

В-третьих, 21 ноября в Риге состоится первый в истории балтийский Perl-воркшоп.

Тесты Perl 1

Набор тестов, входящий в состав дистрибутива Perl 1, выполняется Perl 5.10 на 91%.

В книге Masterminds of Programming, в которой собраны интервью с создателями семнадцати языков программирования, я прочитал, как Ларри Уолл заметил, что многие тесты, которые были написаны для первой версии перла, правильно работают и под Perl 5.

Что ж, пробуем.

Дистрибутив Perl 1 доступен на сайте dev.perl.org. В нем есть папка t, в которой находятся около 50 файлов с тестами:

base.cond, base.if, base.lex, base.pat, base.term, cmd.elsif, cmd.for, cmd.mod, cmd.subval, cmd.while, comp.cmdopt, comp.cpp, comp.decl, comp.multiline, comp.script, comp.term, io.argv, io.fs, io.inplace, io.print, io.tell, op.append, op.auto, op.chop, op.cond, op.crypt, op.do, op.each, op.exec, op.exp, op.flip, op.fork, op.goto, op.int, op.join, op.list, op.magic, op.oct, op.ord, op.pat, op.push, op.repeat, op.sleep, op.split, op.sprintf, op.stat, op.subst, op.time, op.unshift

Имена довольно необычны для современных тестов. В добавок в комплекте есть файл TEST, который выполняет роль современной утилиты prove. Сам этот файл работать не хочет, но prove вполне работает:

$ prove *.*

Сводка с результатом работы выглядит так:

Failed 14/49 test scripts. 26/305 subtests failed.
Files=49, Tests=305,  7 wallclock secs ( 1.39 cusr +  0.47 csys =  1.86 CPU)
Failed 14/49 test programs. 26/305 subtests failed.

Из 305 тестов с ошибкой завершились только 26. И это после 20 лет разрабоки языка, невероятно!