The Advisory Boar

By Abhijit Menon-Sen <>

Trying out Mojolicious


For the first time in many years, I have a new web project to work on (and perhaps it goes without saying that I need to finish it quickly). Much has changed in the world of web development with Perl since I was last seriously involved, and it took me a while to find my bearings.

When I last worked on a major new web project, none of today's popular web development frameworks existed. Tangram was the shiny new ORM (but I can't remember hearing either "ORM" or "CRUD" back then), and ePerl was my favourite out of perhaps half a dozen templating modules on CPAN. Both have long since been forgotten, and I set out to find something to replace them. I had a few very specific ideas about what functionality I wanted, but I suppressed my "not invented here" tendencies and decided to accept any reasonable way to implement them.

The first thing I tried was Jifty, whose basic premise I liked and whose developers I respect. I'd played with it when it was first released, and although I knew there were some things about it that I didn't like, I expected to get along with it well enough to use it in a few projects. I waited while its myriad dependencies were resolved, fixed a couple of dependency-version-related problems, and set out to build a prototype.

Unfortunately, I found Jifty too big to wrap my head around in the time I had, and there just wasn't enough documentation to help me. I know it is actively developed and in use at BestPractical, but I was discouraged by the broken image links on the wiki (no diagrams that may have helped me make sense of things) and the mostly idle IRC channel. Many of the tutorials were either fairly trivial or out of date; and the most detailed one was for a non-trivial project that had later switched to Catalyst. Still, I stuck with it for several days before reluctantly deciding to move on when I couldn't figure out how to implement features I needed and solve problems I encountered along the way.

I knew a number of people who were happy with Catalyst, so I tried that next. It brought with it another set of dependencies, and a lot more documentation. I learned enough about the Catalyst core to decide on a sensible structure for my second prototype, but I found myself lost in a maze of plugins when it came to implementation details. I could never be certain which of the dozen wildly different ways to do any given thing was most appropriate; and once again, features I wanted turned out to be hard to achieve with the most commonly-used and best-maintained plugins. I gave up when I found myself implementing most of the CRUD handling code I needed from scratch. (I also found that I liked DBIx::Class no more than I'd liked Jifty's DBIx::SearchBuilder, which wasn't very much at all.)

By now thoroughly disappointed, I looked for other alternatives and stumbled across Mojolicious and Dancer, two superficially very similar projects that provided only convenient request and response handling in a neat little package. I played with both, and read Adam Kennedy's comparison of the two. I started with Dancer, but ended up choosing Mojolicious for various reasons. First, it had no dependencies other than core Perl (which was an attractive proposition after hours spent installing Jifty and Catalyst). Second, it provided single-file Dancer-like syntax sugar in Mojolicious::Lite, but also offered a way to move beyond that and write a more structured app. I also liked its default templating system (whereas I'd never really liked Template Toolkit, which Dancer prefers). Despite some initial misgivings, once I started using it, I kept finding little reasons to like it.

I'm using Mojolicious (not ::Lite) for my project, and I'm happy so far.

ExtUtils::MakeMaker and the case of the C++ library


I have been working on an XS interface to a C++ library comprising three namespaces split across several source files. I wanted to keep and build these files in their own subdirectory, and have only my .xs file at the top level. This was surprisingly hard to do, and I used a silly hack to make it work—I built my objects as foo.oo instead of foo.o.

The problem is that ExtUtils::MM_Unix's c_o function returns a number of rules to create object files by compiling .c, .cc, and other files, but they all place the resulting object in the top-level directory. I didn't want to redefine everything in c_o, so I tried to override the .cc build rule in MY::postamble. That worked, but caused make(1) to complain about the duplicated rule.

So I picked an unused extension and created a build rule for it:

sub MY::postamble {'
	$(CXX) $(OPTIMIZE) $(DEFINE) $(INC) -o "$@" -c "$<"

That worked perfectly. In my call to WriteMakefile(), I passed the names of the various "subdir/src/foo.oo" files in the OBJECT list. The objects were built by the rule, and EU::MM took care of linking them in. But I still wince a little when I see all the .oo files.

A simpler solution, adopted by Florian Ragwitz in Class::MOP, is to add "-o $@" to the build command in MY::const_cccmd().

Net::XMPP virtual hosting support


I use a Git post-receive hook that sends commit notifications to a Jabber server using the Net::XMPP Perl module.

For the first year or so of its operation, the hook would connect to the Jabber server (first jabberd 1.4, later Ejabberd) that I ran on, and send the commit message as, and all was well. Recently, we reorganised our servers. The git repository stayed in the same place, but we wanted it to connect to the Jabber server on and send notifications as

I run Ejabberd on too, and it was the work of a moment to add to its list of hostnames and create an account for But when I tried to make my hook connect to the new server, I discovered that Net::XMPP does not allow me to specify the name of the server independently of the hostname in the Jabber ID:

my $client = new Net::Jabber::Client ();
    hostname => '',
) or die "Can't connect: $!\n";

my @r = $client->AuthSend(
    username => 'git',
    password => '...',
    resource => 'aox.git'
die "Cannot authenticate (@r)\n" if $r[0] ne "ok";

This code would connect to and try to authenticate as Changing hostname to "" didn't work (even though we had SRV records pointing to the right server). Changing the username to "" didn't work either. I spent some time looking through the code and a tcpdump of the session to understand the problem. It turns out that an XMPP session begins with a <stream> element like this:

<stream:stream version='1.0'

What is needed is to connect to and send to='' in the stream, because Ejabberd rejects connections to a hostname not listed in its configuration.

Net::XMPP and XML::Stream (the underlying module) use the hostname passed to Connect() to decide where to connect and what to send in the <stream>. Furthermore, XML::Stream did support SRV lookups, but it would replace the hostname with the result of the lookup and use that name to compose the stream; and Net::XMPP had no way to enable the SRV lookups anyway.

I whipped up a patch to solve these problems. It adds "servername" and "srv" parameters to the Connect() method, which are passed down to XML::Stream. If the servername is specified, it is used to decide where to connect (and if not, the old behaviour remains unchanged). The srv parameter enables SRV lookups, and the results are used to set (only) the servername; but the hostname is used to compose the stream in every case. Thus the two are separated enough for my hook to work again.

I sent my patch to the module maintainers, but did not receive a reply. The patch is archived here. It applies to Net::XMPP 1.02 and XML::Stream 1.23, but may need minor tweaking to apply cleanly to other versions.

HTTP::Parser 0.04 bugfix


In writing Inspector34, I decided to use the HTTP::Parser module and the corresponding POE::Filter to parse HTTP requests and responses.

I discovered that HTTP::Parser stores the protocol version in an X-HTTP-Version pseudo-header field, which causes LWP to treat the resulting HTTP::Request object as an HTTP/0.9 request (as it is required to do, since no version is explicitly specified). That was certainly not what I wanted.

Since HTTP::Message provides a protocol() method, it seemed sensible to use that instead of X-HTTP-Version. I whipped up a simple patch to do this (and correct a few documentation errors to boot).

I sent this patch to the author, but received no response. It is preserved here for the record.