NAME

Text::PO::MO - Read and write GNU gettext .mo (Machine Object) files

SYNOPSIS

    use Text::PO::MO;
    my $mo = Text::PO::MO->new(
        file             => '/home/joe/locale/ja_JP/LC_MESSAGES/com.example.mo',
        auto_decode      => 1,
        encoding         => 'utf-8',
        default_encoding => 'utf-8',
    );
	my $hash = $mo->read;
	my $hash = $mo->read(
	    file             => '/home/joe/locale/ja_JP/LC_MESSAGES/com.example.api.mo',
	    no_cache         => 1,
	    auto_decode      => 1,
	    default_encoding => 'utf8',
	);

    my $po = $mo->as_object;
    # Using the same possible options as read()
    my $po = $mo->as_object(
	    file             => '/home/joe/locale/ja_JP/LC_MESSAGES/com.example.api.mo',
	    no_cache         => 1,
	    auto_decode      => 1,
	    default_encoding => 'utf8',
    );

    # Writing a .mo file from a Text::PO object
    my $po = Text::PO->new->parse( 'messages.po' );
    $mo->write( $po, {
        file     => 'messages.mo', # or, if not provided, use initial one set in the object.
        encoding => 'utf8',
    }) || die( $mo->error );

    $mo->auto_decode(1);
    $mo->default_encoding( 'utf8' );
    $mo->domain( 'com.example.api' );
    $mo->encoding( 'utf8' );
    $mo->file( '/some/where/locale/en_US/LC_MESSAGES/com.example.api.mo' );
    $mo->revision( '0.1' );
    $mo->use_cache(1);

    $mo->decode( $hash_ref );            # use previously declared encoding
    $mo->decode( $hash_ref => 'utf8' );
    $mo->encode( $hash_ref );            # use previously declared encoding
    $mo->encode( $hash_ref => 'utf8' );

    # Reset cache and last modified timestamp
    $mo->reset;

VERSION

v0.4.0

DESCRIPTION

Text::PO::MO provides an interface for reading from and writing to GNU gettext binary .mo (machine object) files.

The module complements Text::PO by allowing conversion between .po text files and their portable binary representation used at runtime by gettext-enabled applications.

It supports:

  • Automatic character decoding

  • Detection of encoding from the meta-information header

  • Caching of decoded key/value pairs

  • Full writing of .mo files, including:

    • Proper synthesis of the header entry (msgid "")

    • Context keys (msgctxt)

    • Singular and plural forms

    • Deterministic ordering compatible with msgfmt(1)

CONSTRUCTOR

new

my $mo = Text::PO::MO->new( $file, %options );

Creates a new Text::PO::MO object.

It accepts the following options:

  • auto_decode

    Boolean. If true, values returned by "read" are automatically decoded according to "encoding" or the meta-information of the file.

  • default_encoding

    Encoding to fall back to when auto-decoding is enabled and no encoding could be determined from the Content-Type header.

  • encoding

    Explicit character encoding to use when decoding. Has priority over default_encoding.

  • file

    The .mo file to read from or write to. May be given as a path or any Module::Generic::File-compatible object.

  • use_cache

    Boolean. If true (default), results of "read" are cached and reused as long as the modification timestamp of the underlying file does not change.

METHODS

as_object

my $po = $mo->as_object;

Returns the result of "read" as a Text::PO object, allowing direct manipulation of PO elements.

auto_decode

Takes a boolean value and enables or disables auto decode of data read from .mo file.

This is used in "read"

decode

my $ref = $mo->decode( \%hash, $encoding );

Provided with an hash reference of key-value pairs and a string representing an optional encoding and this will decode all its keys and values.

If no encoding is provided, it will use the value set with "encoding"

It returns the same hash reference, although being a reference, this is not necessary.

default_encoding

Sets the default encoding to revert to if no encoding is set with "encoding" and "auto_decode" is enabled.

Otherwise, "read" will attempt to find out the encoding used by looking at the meta information Content-type inside the binary file.

domain

Sets or gets the po file domain associated with the translation catalogue, such as com.example.api

encoding

Sets or gets the encoding used for decoding the data read from the .mo file.

file

my $file = $mo->file( '/some/where/locale/en_US/LC_MESSAGES/com.example.api.mo' );

Sets or gets the gnu .mo file path to be read from or written to.

Returns a file object

read

    my $translations = $mo->read(
	    file             => '/home/joe/locale/ja_JP/LC_MESSAGES/com.example.api.mo',
	    no_cache         => 1,
	    auto_decode      => 1,
	    default_encoding => 'utf8',
    );

Reads the GNU .mo file and returns a hash reference mapping msgid strings to their translated msgstr values.

The empty string key "" corresponds to the special header entry and its meta-information (e.g. Project-Id-Version, Language, Content-Type, etc.).

Recognised options:

  • auto_decode

    Boolean value. If true, the data will be automatically decoded using either the character encoding specified with "encoding" or the one found in the Content-type field in the file meta information.

  • default_encoding

    The default encoding to use if no encoding was set using "encoding" and none could be found in the .mo file meta information.

  • file

    The .mo file to read from.

    If not provided, this will default to using the value set upon object instantiation or with "file".

  • no_cache

    Boolean value. If true, this will ignore any cached data and re-read the .mo file.

If caching is enabled with "use_cache", then "read" will return the cache content instead of actually reading the .mo unless the last modification time has changed and increased.

Note that the <.mo> files store the elements in lexicographical order, and thus when reading from it, the order of the elements might not be the same as the one in the original .po file.

Upon error, this sets an error object, and returns undef in scalar context, and an empty list in list context.

reset

$mo->reset;

Resets the cached data. This will have the effect of reading the .mo file next time "read" is called.

Returns the current object.

revision

Sets or gets the .mo file format revision number. This should not be changed, or you might break things.

It defaults to 0

use_cache

Takes a boolean value.

If true, this will enable caching based on the .mo file last modification timestamp.

Default to true.

write

$mo->write( $po, \%options );

Writes a binary .mo file from a Text::PO object, adding all the elements lexicographically, as required by GNU machine object format.

Supported options are:

  • file

    The output file to write the data to.

    Defaults to the object's file attribute.

The method:

  • Synthesises the header entry from $po->meta (msgid "")

  • Supports context (msgctxt) and plural forms

  • Concatenates plural translations using NUL separators

  • Writes deterministic index tables as required by GNU gettext

THREAD-SAFETY

This module is thread-safe. All state is stored on a per-object basis, and the underlying file operations and data structures do not share mutable global state.

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

Text::PO, Text::PO::Element

https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html

http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html#MO-Files

COPYRIGHT & LICENSE

Copyright (c) 2020-2025 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.