The Right Approach to Exceptions
H. S. Teoh
hsteoh at quickfur.ath.cx
Mon Feb 20 10:32:13 PST 2012
On Mon, Feb 20, 2012 at 12:19:57PM -0600, Andrei Alexandrescu wrote:
[...]
> Maybe this is all a misunderstanding. Allow me to explain what the
> intent is. I suggest we add a method (better than a member, upon
> further thinking):
>
> class Exception : Error
> {
> Variant[string] info()
> {
> return null; // no extra info here
> }
> ...
> }
>
> Classes that inherit Exception may override info:
>
> class GetOptException : Exception
> {
> Variant[string] info()
> {
> return [ "flag" : _flag ];
> }
> ...
> string _flag;
> }
>
> Now code that wants to handle GetOptException specifically can
> definitely do so. The advantage of defining info() is that now we
> get to write code that does not need duplication across all concrete
> types, but instead gets to use Exception.info in conjunction with
> various formatting and rendering engines. Again, it's simple OO
> design.
[...]
Couldn't this be achieved like this?
class Exception : Error {
string formatMsg(LocaleInfo li) {
// Default behaviour
return formatLocale(li, msg);
}
}
class GetOptException : Exception {
string flag;
string formatMsg(LocaleInfo li) {
return formatLocale(li, fmt, flag);
}
}
Or, if you want to eliminate defining formatMsg() in every non-trivial
derived class, just use some form of class reflection, so you'll have
something along these lines:
class Exception : Error {
string formatMsg(LocaleInfo li) {
LocaleMsgArgs args;
foreach (attr; reflect.attributes(this)) {
// Have some naming convention to decide
// which fields get picked up.
if (attr.name.startsWith("info")) {
args.append(this.reflect.attrvalue(attr));
}
}
return args.format(li);
}
}
class GetOptException : Exception {
string infoFlag; // this gets picked up by formatMsg
int internalVar; // this doesn't
...
}
T
--
Everybody talks about it, but nobody does anything about it! -- Mark Twain
More information about the Digitalmars-d
mailing list