[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-i18n-doc
Subject:    Re: KGeography needs your help
From:       Nicolas Goutte <nicolasg () snafu ! de>
Date:       2005-08-11 13:27:28
Message-ID: 200508111524.36731.nicolasg () snafu ! de
[Download RAW message or body]

On Thursday 11 August 2005 04:57, Chusslove Illich wrote:
> > [: Nicolas Goutte :]
> > However if the class has its own private class d, like any good public
> > KDE class, you do not care if d constains (in Qt4 classes) QString,
> > Q3CString, QByteArray or std::string . And you do not have to change
> > your binary compatibility.
>
> While trying this approach, I even put a QString member variable outside of
> private class :) (The only other thing outside is a boolean, specifying if
> scripting is on or off.) I did this in order to avoid any unnecessary
> overheads when scripting is turned off, so that currently I even don't
> have to allocate the private class if scripting is off.

>
> I also didn't feel a pressing need to eliminate QString. Everything else in
> KDE/Qt is rifled with it, and it was a previous choice for i18n. Even
> Stephan said in that other message that he doesn't mind "if i18n returned
> a class deriving from QString".

Yes, but look at the current i18n(). Most of the processing is not done as 
QString but as const char*. So why should it derive from QString?

Similar, your Scheme implementation seems to use strings that are byte arrays.
So why would KI18n not derive from Qt4's QByteArray instead? Probably it 
should not, but then the main data that you keep in KI18n could be a 
QByteArray instead of a QString.

QString is only the return value of i18n() and I think that it should be kept 
so in the class.

>
> > Also books about OO programming tell to derive one class from another
> > if there are of a same kind. That is not eaxctly the case here, as
> > QString is a class for holding a string and KI18N is for processing
> > translations.
>
> Yes, I also feel some confusion with is-a/has-a distinction here, but one
> can say that KI18n is a QString, but a smarter one, which knows how to
> translate itself into another language :)

But i18n() does not has a QString parameter.

>
> There is a practical problem too, programmer can do (and does) something
> like:
>
> QString tmp = i18n("Blah, blah, %1");
> ...
> tmp.arg(somearg);
>
> Here the translation would be forced at the point of assignment, and script
> wouldn't be called at all because not all arguments have been supplied.
> But to avoid this, not only that KI18n shouldn't be inherited, but there
> shouldn't even be QString cast operator in non-inherited KI18n class. This
> would result in the cleanest solution, but breaking *all* current i18n
> code and programming habits:
>
> QString msg = i18n("Blah, blah, %1").arg(somearg).t();
>
> where method t() would stand for "it's assembled, translate it".

Yes, but that is clearly very different from what we have nowaday. That is 
more complex than changing some QString declarations into KI18n declarations, 
as the "magic" function t() would be needed everywhere.

>
> So, if we don't want to break all i18n code and programming habits, than
> perhaps solution with inheritance is not that different from the
> non-inherited with implicit cast to QString.
>
> That problematic programming practice above would be treated as breaking
> the rule of "not splitting the messages", and requiring a fix, but
> luckilly a very easy one.
>
> >> [: Chusslove Illich :]
> >> There is one other thing that is bugging me though: QString doesn't
> >> have virutal destructor [...] I have also declared operators new and
> >> delete to be private [...]
> >
> > [: Nicolas Goutte :]
> > See, because you have derived one class from another, you are starting
> > to "peek and poke" around. That are clear signs that the derivation is
> > bad.
>
> Not only the allocation operators, but also arg() methods are overridden
> since they are not virtual in QString.
>
> But these problems for themselves are not a cause of bad design alarm to
> me, because they exist for the reason that in C++ as a language this point
> is moot. Like, invariants of inheritance should be kept non-virtual, and
> other methods virtual, but QString actually has nothing virtual.

Sorry, with my experience, that are all points that are asking for trouble. 
And once you would have trouble, it would be too late to change back, as we 
would probably be in full binary compatibility. (Or worse, it breaks 
immediately the binary compatibility.)

You can see such bad examples with the KTar and KZip classes, with the complex 
virtual_hook implementation, because somebody had forgotten some virtuals in 
the base class. Once you have started, it is too late to go back and change 
implementation decisions.

>
> >> [: Chusslove Illich :]
> >> 125 changes were needed because KGuiItem has a constructor that takes a
> >> QString, and it was called by passing result of i18n to it.
> >
> > [: Nicolas Goutte :]
> > But then we can add a constructor with KI18N as parameter. [...]
>
> I tried, but at some places the method which was taking result of i18n()
> call could either be invoked with a QString or KGuiItem, again making
> compiler refuse to make a choice (use implicit KI18n->QString, or implicit
> KI18n->KGuiItem?)
>
> > [...] Or add an operator that returns KGuiItem.
>
> This cannot be, as KI18n is in the kdelibs/kdecore which depends only on
> kdelibs/dcop, KGuiItem is higher up.

Too bad!

>
> >> [: Chusslove Illich :]
> >> Most of the rest of explicit casts (75) were needed due to invoking
>
> methods
>
> >> local8Bit() and length() directly on result of i18n call.
> >
> > [: Nicolas Goutte :]
> > You can have there funtions as members of KI18N. That is not the
> > problem. But compared of directly deriving from QString, you are
> > controlling the interface.
>
> This I thought of, but I don't like it. If we are going to try to mimic
> QString with KI18n by adding methods same as those in QString, then we
> loose the advantage of not inheriting from QString in the first place.

It is not really mimicing. You control the interface.

In the I18N Howto, there are things like:
- do not use QString::latin1
- do not use QString::local8bits (except rare cases)
- always use QString::utf8()

So KI18n could control this and avoid that the developers forget about such 
details by only implementing QString::utf8() (and the new name that was 
introduced in Qt4.)

The goal is to make a clean class. You do not know how the class will evolve. 
You do not know what will be planned with this class in KDE5. You do not know 
what plans Trolltech will have with QString in Qt5.

You have the chance now not to mix both classes. If at Qt5/KDE5, youwill wnat 
to split them, you will probably have much more work, because people will 
have mied KI18n and QString. And then you will really need to give KI18n the 
full interface of Qt4's QString.

(...)

Have a nice day!

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic