digitalmars.D.learn - Subclass of Exception
- Paul (11/11) Jun 14 2014 One stupid question: in Python subclassing of Exception looks
- FreeSlave (48/59) Jun 14 2014 In this regard D is same as C++. When you create derived class,
- Paul (2/64) Jun 14 2014 Thank you!!
- bearophile (6/10) Jun 14 2014 Don't call exceptions errors, because in D there are also errors,
- Jonathan M Davis via Digitalmars-d-learn (45/56) Jun 14 2014 If you're creating an exception that doesn't take any new arguments (so ...
One stupid question: in Python subclassing of Exception looks like: class MyError(Exception): pass but in D, if I'm right, we should write more code: class MyError : Exception { this(string msg) { super(msg); } } (without constructor we get error: "...Cannot implicitly generate a default ctor when base class <BASECLASS> is missing a default ctor...") Is any shorter D way?
Jun 14 2014
On Saturday, 14 June 2014 at 11:59:53 UTC, Paul wrote:One stupid question: in Python subclassing of Exception looks like: class MyError(Exception): pass but in D, if I'm right, we should write more code: class MyError : Exception { this(string msg) { super(msg); } } (without constructor we get error: "...Cannot implicitly generate a default ctor when base class <BASECLASS> is missing a default ctor...") Is any shorter D way?In this regard D is same as C++. When you create derived class, you need to define constructors, even if all they do is passing arguments to base class' constructor. It's really annoying, especially when base class has many constructors. But in D you can apply some template magic to automate this process for exceptions. Example: import std.stdio; template TemplateException(T) { class TemplateException : Exception { public: this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } } } void throwException(Exception ex) { try { throw ex; } catch(TemplateException!int e) { writeln("int"); } catch(TemplateException!double e) { writeln("double"); } catch(TemplateException!string e) { writeln("string"); } } int main() { auto intEx = new TemplateException!int("int error"); auto doubleEx = new TemplateException!double("double error"); auto stringEx = new TemplateException!string("string error"); throwException(intEx); throwException(doubleEx); throwException(stringEx); return 0; } You also can tempalte with string literals instead of types to gain more flexibility and use alias statement to provide convenient names.
Jun 14 2014
On Saturday, 14 June 2014 at 12:17:46 UTC, FreeSlave wrote:On Saturday, 14 June 2014 at 11:59:53 UTC, Paul wrote:Thank you!!One stupid question: in Python subclassing of Exception looks like: class MyError(Exception): pass but in D, if I'm right, we should write more code: class MyError : Exception { this(string msg) { super(msg); } } (without constructor we get error: "...Cannot implicitly generate a default ctor when base class <BASECLASS> is missing a default ctor...") Is any shorter D way?In this regard D is same as C++. When you create derived class, you need to define constructors, even if all they do is passing arguments to base class' constructor. It's really annoying, especially when base class has many constructors. But in D you can apply some template magic to automate this process for exceptions. Example: import std.stdio; template TemplateException(T) { class TemplateException : Exception { public: this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } } } void throwException(Exception ex) { try { throw ex; } catch(TemplateException!int e) { writeln("int"); } catch(TemplateException!double e) { writeln("double"); } catch(TemplateException!string e) { writeln("string"); } } int main() { auto intEx = new TemplateException!int("int error"); auto doubleEx = new TemplateException!double("double error"); auto stringEx = new TemplateException!string("string error"); throwException(intEx); throwException(doubleEx); throwException(stringEx); return 0; } You also can tempalte with string literals instead of types to gain more flexibility and use alias statement to provide convenient names.
Jun 14 2014
Paul:class MyError : Exception { this(string msg) { super(msg); } }Don't call exceptions errors, because in D there are also errors, so they should have distinct names.Is any shorter D way?Perhaps not. Bye, bearophile
Jun 14 2014
On Sat, 14 Jun 2014 11:59:52 +0000 Paul via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:One stupid question: in Python subclassing of Exception looks like: class MyError(Exception): pass but in D, if I'm right, we should write more code: class MyError : Exception { this(string msg) { super(msg); } } (without constructor we get error: "...Cannot implicitly generate a default ctor when base class <BASECLASS> is missing a default ctor...") Is any shorter D way?If you're creating an exception that doesn't take any new arguments (so it's just its type that's important rather than it having any new members), then the typical declaration would be /++ My exception type. +/ class MyException : Exception { /++ Params: msg = The message for the exception. file = The file where the exception occurred. line = The line number where the exception occurred. next = The previous exception in the chain of exceptions, if any. +/ this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) safe pure nothrow { super(msg, file, line, next); } /++ Params: msg = The message for the exception. next = The previous exception in the chain of exceptions. file = The file where the exception occurred. line = The line number where the exception occurred. +/ this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) safe pure nothrow { super(msg, file, line, next); } } There have been attempts to write mixins or templates which generate this for you - e.g. mixin(genExceptionType("MyException")); but then you can't have documentation on it, because mixed-in code is not examined when the documentation is generated, and you can't document the mixin itself. So, at this point, it just makes the most sense to take my example, change its name and documentation, and then use that rather than trying to generate it - though if you don't care about documentation at all (which is usually a bad idea but might make sense on small projects), then it would be simple enough to create a function which will generate the string to mix in for you. - Jonathan M Davis
Jun 14 2014
I don't think you always need documentation for all exception classes, since the most of them have the same interface. Usually it's worth to describe where is some exception able to be thrown from, not exception itself. And it's covered by function documentation, not by documentation of exception class. If you need to just mention exception class in documentation then my method is way to go, because you can document alias declaration, and mention that it has same interface as Exception (not difficult to remember).
Jun 15 2014
On Sunday, 15 June 2014 at 09:23:36 UTC, FreeSlave wrote:I don't think you always need documentation for all exception classes, since the most of them have the same interface. Usually it's worth to describe where is some exception able to be thrown from, not exception itself. And it's covered by function documentation, not by documentation of exception class. If you need to just mention exception class in documentation then my method is way to go, because you can document alias declaration, and mention that it has same interface as Exception (not difficult to remember).Thanks a lot
Jun 15 2014