On 2/20/12 7:08 PM, H. S. Teoh wrote:
On Mon, Feb 20, 2012 at 06:38:08PM -0600, Andrei Alexandrescu wrote:
[...]
We shouldn't be using Variant[string] for this, because there's
another problem associated with it: suppose MyException sometimes
gets "extra_info1" and "extra_info2" tacked onto it, on its way up
the call stack, and sometimes not. Now what should the catcher do?
Use a central loop to render the information.
Then it's useless for i18n, unless you can magically translate a
sequence of unknown values into a different language in a consistent
way.
It sounds like all this is good for is to print a list of "name=value"
pairs. Which is useful, I'll admit, for development/debugging purposes.
I don't see how such a thing is useful in i18n.
As I said, string templates in conjunction with name/value bindings is
all that's needed for i18n.
[...]
This is what I mean by not being able to depend on whether some data
is there. Ultimately, to do anything useful with the info in the
object, you need to know what's there.
No. You do realize you are positioning yourself straight against every
OO principle there is? The entire OO world is predicated on the
assumption you _can_ do useful stuff with an object WITHOUT knowing
what's there.
And the way OO does this is by having the *derived classes* do useful
stuff behind a polymorphic interface.
Exactly, and with this you just destroyed your own design. For it does
not build any polymorphic interface, no abstraction. It forever forces
code to toil in the concrete (_fileName, _ipAddress, _userName) and
fails to elevate any common interface that would foster reusable code.
What the Variant[string] does is,
as you have said previously, to replace the need for many derived
classes save a few, thereby throwing away the polymorphism and
presenting what amounts to an array of void* to the catch block.
On the contrary. This builds abstraction:
class Exception
{
bool transient();
Variant[string] info();
...
}
because it allows client code to treat different types, even types that
haven't even been defined yet, uniformly.
This does not build anything:
class Exception {}
class UserNameException : Exception { string _userName; }
class NetException : Exception { string _ipAddress; }
...
For you to now accuse me of going against OO principles is a really
strange argument, I must say. I was in fact *advocating* the use of OO
by putting the useful information in the derived classes, where they
belong.
I'm not accusing of anything, merely noting that your design does not
stand the scrutiny of your own principles (which are correct). Both
can't be sustained simultaneously. Try a fresh run of your principles
over your design. It'll get totaled.
I think you are misunderstanding the mechanisms involved. There is no
combinatorial code, just simple iteration and such. Dealing with
distinct exceptions with distinct code IS combinatorial, repetitive,
and non-scalable.
Then pray tell how "simple iteration" will achieve the translation of
the data in Variant[string] into a localized string, when there is no
guarantee any field will be in the hash at all. Format strings obviously
won't work, since you can't have a format string unless you already know
what arguments are present.
There's no guarantee. That'll be a runtime check in the formatting engine.
Andrei