Am Dienstag, den 14.08.2007, 10:59 +0800 schrieb manphiz:
The compose and format API saves C++ from gettext a lot. And it reminds
me a similar library of boost::format [1], which basically does the same
thing, but provides different interfaces. I'm not an expert, but I
believe the Boost one might be better than yours in the following 2 aspects:
Thanks a lot for your feedback. I just had a look at the boost format
API. It's actually quite similar to my proposal despite the apparent
differences. Let's see:
1. format-string specification
boost::format retains the old printf format (%spec), and provides more
flexible syntax, such as %|spec| which can omit the type-conversion
character, as well as %N% which plays as place holder, while you were
using %N as place holder. The lack of printf-like format might results
in incompatible interfaces with plain printf and might compromises the
interoperability of format string with other printf-like functions.
Though they are definitely not good choices, they are still widely used.
However, you can implement the same thing of course :)
Interesting. Apparently boost allows printf syntax to control output
formatting while ignoring the implied type information, since the latter
is determined at compile time. Nice idea but probably overkill, as it
also supports I/O manipulators. Although supporting both would allow
the programmer to yield control over the format to the translator. Are
there valid use-cases for this? Generally it's cleaner to only allow
reordering.
With regards to interoperability with printf I don't see the problem,
except perhaps for a lack of familiarity with the format on the part of
the translators. However, the syntax is extremely simple and intuitive,
and any mistakes should hopefully be caught by msgfmt when run with the
"--qt" option. As it happens I'm already using this syntax in regexxer
and there has been only one accidental mistranslation as far as I can
remember.
Conceptually there isn't much of a difference between the two APIs:
s1 = ustring::compose("%1 is lower than %2.", "12", "34")
s2 = boost::format("%1 is lower than %2.") % "12" % "34"
Granted, with non-string arguments it gets uglier:
s1 = ustring::compose("%1 is lower than %2.", ustring::format(12),
ustring::format(34))
s2 = boost::format("%1 is lower than %2.") % 12 % 34
Interestingly, boost introduces a group() function to avoid the
ambiguity that arises when I/O manipulators are used. group() is
actually very similar to ustring::format(), except that it can be
omitted if no grouping is necessary. So it seems there are now three
API variations to choose from:
// 1) status quo
s1 = ustring::compose("%1 is lower than %2.",
ustring::format(12),
ustring::format(std::setprecision(1), 34.5))
// 2) boost-ish
s2 = ustring::format("%1 is lower than %2.")
% 12 % group(std::setprecision(1), 34.5)
// 3) half-breed
s3 = ustring::format("%1 is lower than %2.",
12, group(std::setprecision(1), 34.5))
Hm, now that I think of it I actually like options 2) and 3) better than
my original proposal. Implementing 3) should be fairly straightforward
but 2) might require some additional bloat. I'll have to give it a try
to be sure though.
Have your say: Which would you prefer?