www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Subclass of Exception

reply "Paul" <aquagnu gmail.com> writes:
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
next sibling parent reply "FreeSlave" <freeslave93 gmail.com> writes:
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
parent "Paul" <aquagnu gmail.com> writes:
On Saturday, 14 June 2014 at 12:17:46 UTC, FreeSlave wrote:
 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.
Thank you!!
Jun 14 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
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
parent reply "FreeSlave" <freeslave93 gmail.com> writes:
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
parent "Paul" <aquagnu gmail.com> writes:
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