Boost logo

Boost :

Subject: Re: [boost] [locale] Review. Internationalization library?
From: Vicente BOTET (vicente.botet_at_[hidden])
Date: 2011-04-16 12:13:16


> Message du 16/04/11 15:01
> De : "Artyom"
> A : boost_at_[hidden]
> Copie à :
> Objet : Re: [boost] [locale] Review. Internationalization library?
>
> >
> > I have made a diagonal reading and I find your library really interesting. I
> >think I will spent quite more time reviewing it.
> >
> > I have just a first minimal and formal remark. When I see the overloading of
> >the translate function
> >
> > message boost::locale::translate (char const *msg)
> > message boost::locale::translate (char const *context, char const *msg)
> > message boost::locale::translate (char const *single, char const *plural, int
> >n)
> > message boost::locale::translate (char const *context, char const *single,
> >char const *plural, int n)
> > message boost::locale::translate (std::string const &msg)
> > message boost::locale::translate (std::string const &context, std::string
> >const &msg)
> > message boost::locale::translate (std::string const &context, std::string
> >const &single, std::string const &plural, int n)
> > message boost::locale::translate (std::string const &single, std::string const
> >&plural, int n)
> >
> > this let me think that it would be difficult to know know what is the
> message,
> > the context, the domain, whether the message is the singular or plural form.
>
> This is the general concept of how gettext used around. So I stick with its
> conversion
> extending it, same concept used in Qt. It is quite common.
>
> I agree that it is not perfect but it seems to be ok.

I'm sure that you will reach to provide something clearer that don't adhere to gettext (which is hidden for the user).

> > The equivalent for (w)gettext uses the c-like idiom, i.e. uses different
> >names.
> >
> > std::string boost::locale::gettext (char const *id, std::locale const
> >&loc=std::locale())
> > std::string boost::locale::ngettext (char const *s, char const *p, int n,
> >std::locale const &loc=std::locale())
> > std::string boost::locale::dgettext (char const *domain, char const *id,
> >std::locale const &loc=std::locale())
> > std::string boost::locale::dngettext (char const *domain, char const *s, char
> >const *p, int n, std::locale const &loc=std::locale())
> > std::string boost::locale::pgettext (char const *context, char const *id,
> >std::locale const &loc=std::locale())
> > std::string boost::locale::npgettext (char const *context, char const *s, char
> >const *p, int n, std::locale const &loc=std::locale())
> > std::string boost::locale::dpgettext (char const *domain, char const *context,
> >char const *id, std::locale const &loc=std::locale())
> > std::string boost::locale::dnpgettext (char const *domain, char const
> >*context, char const *s, char const *p, int n, std::locale const
> >&loc=std::locale())
> >
> > Neither is satisfying me.
>
>
> These are mostly gettext compatibility functions so users familiar
> with gettext would find themselves with (almost) same API.

You are not forced to provide C-like interfaces in a Boost library to content some users that know the gettext interface. It is quite ugly.

> > I was wondering if the use of Boost.Parameters could help.
> >
>
> I'm not really familiar with Boost.Parameters but from quick glance it requires
> not-so trivial template metaprogramming but what is even more important
> I'm afraid that things like
>
> translate(context_ = "File","Open")

I had no issue explaining this idiom to users of a library. Another question is for the implementer of the library, some more explanation will be needed.

> May scary off some average C++ programmers that would not understand what
> is this thing
>
> context_ = "File"
>
> Finally I want Boost.Locale be used by not brilliant C++ programmers as well.
>
> I know what hard times I have explaining about boost::bind to average
> C++ programmers so making things like that would not help too much.

Well, it is your library. It is up to you to maintain ugly interfaces like the preceding ones.
>From my side the add a -1 to the review. Fortunately there are a lot of positive parts.

> > An alternative could also be to define some thin wrappers that state clearly
> >what is the meaning of the string or const char * parameters, for example we
> >could have
> >
> > struct domain {
> > domain(const char*);
> > domain(std::string const&);
> > operator const char*() const;
> > operator std::string() const;
> > };
> >
> > The same for context, plural.
> > Note that we don't need to wrap the message itself as this parameter is
> >mandatory.
> >
> > The examples
> >
> > cout << format(translate("You have 1 file in the directory",
> > "You have {1} files in the directory",files)) % files << endl;
> >
> > button->setLabel(translate("File","open"));
> >
> >
> > could be written as
> >
> > cout << format(translate("You have 1 file in the directory",
> > plural("You have {1} files in the directory"),files)) % files << endl;
> >
> > button->setLabel(translate(context("File"),"open"));
> >
> > With this modification, the (w)gettext could all share the same names and
> >there
> > will be no need to use c-like names.
> >
> > What you think?
>
> This one more interesting. However there an important point to check:
>
> Integration with xgettext - would it be able to read this or entire new
> xgettext should be developed to extract strings.

I don't understand. Could you clarify, please?
For me all the gettext functions should share the same name as well as all all the wgettext. No need to use the prefixed 'p' 'd' ...

> I need to think about, probably it may be an alternative.

You could also associate the translate function to the context object

button->setLabel(context("File").translate("open"));

This can be extended to the domain,

button->setLabel(domain("D").context("File").translate("open"));

but doesn't scale well for the plural parameter.

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk