Migrating from Locale::Maketext to Locale::TextDomain

Inspired by a recent Perl advent article, I'm migrating my CPAN distributions from using Locale::Maketext to Locale::TextDomain.


  • I get to use all the available gettext tools (for scanning translateable strings, for merging and updating them to each translation file, specialized text editors for editing translation, etc). This is the definitely nicest thing about the migration. With David Wheeler's Dist::Zilla plugin, the workflow is basically 'dzil msg-scan', 'dzil msg-merge', and update translations (the plugin will do 'dzil msg-compile' for you during build).

  • I no longer need to create project (translation) classes. I've always disliked having to do that, especially if my module or application is not OO.

  • I get named parameters for values. Instead of having to write [_1], [_2], etc, I can now use {foo}, {bar} instead. Translation text become clearer.


  • Slightly increased startup overhead. With Locale::Maketext you can embed the translation directly in Perl source code (in __DATA__ sections). With Locale::TextDomain the application will have to search message catalog files. Whether this overhead is significant or not will depend on your case. In most practical cases, the difference should not be that significant.

Some other notes:

  • The current version of the dzil plugin (0.88) by default does not scan bin/ or script/. Sent a pull request for that.

  • When your module is OO, Locale::Maketext allows you to set a hierarchy for finding translation text. For example, my module A is subclassed by B. B project classes can extend A's, so translation text are searched in B and then A. I'm not sure how this setup usually works in Locale::TextDomain (whether both A and B use the same textdomain or not, whether you merge A's messages into B's message catalog).

Thanks David for the article and dzil plugin.


While Locale::Maketext has its problems, its design is superior to the one of gettext. For me the biggest problem with gettext is that its behaviour defined by global environment variables. It may work ok for local applications, but for server application it creates a problem. Imagine CGI script serving page to Indonesian client (and therefore having LANG set to the appropriate value) fails to open a file, guess what language the error message in error log will be in? And what if you have some event loop based webserver, with single process serving dozens of clients with different language preferences simultaneously?

Leave a comment

About Steven Haryanto

user-pic A programmer (mostly Perl 5 nowadays). My CPAN ID: SHARYANTO. I'm sedusedan on perlmonks. My twitter is stevenharyanto (but I don't tweet much). Follow me on github: sharyanto.