Tuesday, 30 November 2010

Perl: Separating the persistence and the business model layers - Part 1

Today, thanks to modern Perl technologies a growing number of Perl project use DBIx::Class to access the database, and a MVC engine, such as Catalyst or other frameworks and a nice template engine to expose the application on the web. Usually, the framework tutorial assumes that you will use DBIx::Class to access and store your objects from your MVC controller. I think this approach is wrong for the following reasons:

- DBIx::Class is a perfectly fine ORM mapper but it's not a business model framework. You can add business code to the result Classes but what happens if you want to migrate some of your stuff to a NoSQL storage? Or change the way some stuff is stored in the DB. Things can and will get ugly.

- Dbic objects do not provide the flexibility you would need to implement common object oriented patterns. What if you want to use Roles, enforce interfaces, implement your own search facility? You'll eventually get so much application business code in your Dbic object that they will no longer look like dbic objects.

- Your web framework is directly fed with the ORM model, and because you want to code things quickly, you start putting business code in your controller, and this business code assumes you're using this or that ORM. And the rest will come. Web applications are difficult to test for regressions, especially if they use Ajax. Things will break without being detected before release, you will fix them quickly in your controller, and as time goes on, your shiny new application using modern Perl technologies will end up being as difficult to maintain as a good old CGI mud-ball.

- What if you want to turn your application into an API? Or if you want to make command line tools for quick administration, or for asynchronous runs? Well you can't. Because the your business logic is scattered everywhere, in all the layers of the application.

What we end up with this approach is our persistence layer and our MVC layer (and in the worst case our template layer) become polluted with a blob of sloppy hard to maintain business model code. Also the sad thing is that your business code IS your business' added value, so it shouldn't be considered polluting something else. I don't think MVC's and ORM's are designed to be the natural container of your business code. I think they should be kept, and loved, and used for what they are: an easy and fast way of making non-business related code thin and minimalistic.
Blob of business code longing for a home on its own

For the development of libsquare.net, I've designed a reasonably fast and easy solution to this problem. I'll be talking about it in the next part of this sequence.

Friday, 5 November 2010

XeTeX: Breaking long lines of Japanese (and Chinese) text.

While LaTeX/XeTeX is very good at hyphenating Latin words, I recently came across the problem of overflowing boxes when attempting to typeset a long paragraph consisting exclusively of Japanese characters:

母親が育児を放棄した末、大阪市西区のマンションで幼い姉弟が亡くなった事件。多くの住民が異変に気づきながら、児童相談所(児相)に通報したのは1人だけだった。複数の人が通報していれば、児相の危機感も強まったかもしれない。なぜ通報をためらった


When you render this with XeTeX, you've got a warning that your hbox is overfull, and the rendered result shows an awful truncated Japanese line:

Rendering of an non hyphen-able Japanese line
We clearly need to fix this, because most of the time your data will be in the form of a long paragraph without any linebreaks.

In XeTeX-notes.pdf, we learn that we can activate the line-breaking in XeTeX by using:

\XeTeXlinebreaklocale"en"

The locale used doesn't matter much, the important thing is that it activates line breaking for too long lines where the hyphenation mechanism cannot do its job (a long Japanese/Chinese line for instance).

By adding this to your preamble, here's what you get:

A Japanese paragraph with line breaks.
Et voilà, lines are broken so all the characters fit in the page width!

Ps: Thanks to Google news Japan for providing example data.

Thursday, 7 October 2010

Perl Postgresql Test Harness

These days, I'm developing pg_cryobit, a piece of software that'll allow you to manage your PostgreSQL continuous backup strategy with ease.

I stumbled upon Test::postgresql, and at first I was a bit suspicious about it, given the fact the latest version is not recent and that there's no debian build of it.

I decided to give it a go anyway. I installed it manually, and only one dependency needed another manual install. The other ones come as a debian packages (This is one reason why I don't quite like to use the cpan shell).

The tests went smoothly, and in no time I had instances of PostgreSQL ready to test with my own software.

I definitely recommend using it if you're writing PostgreSQL dependent software.

Has anyone has experience with the MySQL flavour of it?

Wednesday, 6 October 2010

Bugs: Importance classification

Dave Child recently posted his thoughts about bug/feature priorities and asked for contributions, here's mine :)

- Blocker: Prevent any operation on the system to happen.

For instance, your app server conf file is wrong, so it won't even start. Or there's a syntax error in one of your top template. This should never pass your test phase (if it does, you've got a problem).

- Critical: A major feature of the system is broken (or missing in case it's a feature ticket) and prevent the business from operating normally. This should never pass the test phase neither.

Example: If you've got an e-commerce website, the cart does not work, or the checkout is broken.

- Normal: A minor feature of the system does not work, or a major feature doesn't work in a particular case.  This could pass the test phase, but it will hurt your reputation.

For instance, your 'share with a friend' link is broken, or the contact us page doesn't work.

- Minor: A subfeature does not work, or a minor feature is broken in a particular case. For instance, redimensioning a textarea doesn't work, failing to provide a valid email in the contact page voids your avatar photo. This could pass the test phase, but only a few of your clients will notice.

- Trivial: Do not prevent anything from working correctly, but still cam harm your reputation.

Example: No feedback to confirm a user has saved its preferences, spelling mistakes, weird ordering etc..

Using this classification, and if you've got an appropriate test plan, your clients should never be exposed to any bugs more important than Normal, ideally only Minor.

Thursday, 23 September 2010

MySQL: Changing the order of a table column

In an ideal purely standard SQL world, one should never have to care about the order of a table's columns. But we're not in an ideal world, and sometime we want to change the position of a table column. Here's how to do it:


ALTER TABLE mytable MODIFY column_move <WHATEVER TYPE IT IS>  AFTER another_column

Note that you need to MODIFY the column with its exact type not to loose any data. Copy/Pasting is your friend here. You can also use BEFORE instead of after.

Saturday, 18 September 2010

Version names brainstorming

Recently we had a brainstorming session in the office to find ubuntu-style version names for our product. Here's my list of suggestions:


Anemic Antelope
Blistering Barnacle
Crying Crocodile
Dubious Donkey
Emotive Elephant
Fiddling Fugu
Grumpy Giraffe
Hairy Haddock
Introvert Impala
Jolly Jellyfish
Kitschy Kitten
Lubricious Lama
Mystical Magpie
Nyctalopic Nautilus
Operatic Oppossum
Persistant Pinguin
Quantitative Quahog
Refreshing Rodent
Suspicious Salamander
Tickling Tiger
Ultramarine Unicorn
Voluptuous Vixen
Witty Wapiti
Xenomorphic Xenopus
Yummy Yeti
Zooming Zebu

Sometime, software engineering requires a bit of poetry :)

Tuesday, 14 September 2010

Perl: How to release a developer only version to CPAN

If you're about to release a new module and have some beta testers, it's probably a good idea to release a developer only version first and then switch it to a final version number after your beta testers (that includes you :) ) are happy with it.

To do that, simply appends the release candidate number at the end of your version number. To release the first dev RC version of version 0.07, simply do:

our $VERSION = '0.07_01';


In your main package.

The CPAN will detect it and make your release a dev release only.

Monday, 13 September 2010

LaTeX: Hyphenate single long words in narrow tabular columns

Consider the following LaTeX code:

\documentclass{article}
\usepackage[english]{babel}
\begin{document}
\begin{center}
    \begin{tabular}{ | p{2cm} | l | l | p{5cm} |}
    \hline
    Incredibilidable & foo & bar & baz \\
    \hline
    \end{tabular}
\end{center}
\end{document}

When you render it, the first column overflows on the second one because 'Incredibilidable' is considered to be the first word of a paragraph, and LaTeX does not hyphenate first words of paragraphs. So here's what you get: 
And this doesn't look nice.

To fix this, we're going to tell LaTeX our word is no longer the first of the paragraph. To do that, we insert a zero length horizontal space before it:

  \hspace{0pt}Incredibilidable & foo & bar & baz \\

The rendering now turns into:

Et voila!