digitalmars.D - This feels wrong
- Shachar Shemesh (43/43) Feb 02 2016 Please consider the following program:
- Marc =?UTF-8?B?U2Now7x0eg==?= (9/9) Feb 02 2016 It seems this is a natural consequence of the lowering. As such,
- Steven Schveighoffer (4/46) Feb 02 2016 Just put try around the opApply specific parts you want to monitor.
- Shachar Shemesh (21/23) Feb 02 2016 The call to dg is, obviously, part of a loop. That whole loop body is
- Steven Schveighoffer (19/26) Feb 02 2016 I don't see a big difference from this:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/7) Feb 02 2016 Good catch! Please either open a documentation bug for this or fork the
- Shachar Shemesh (2/9) Feb 03 2016 https://github.com/D-Programming-Language/dlang.org/pull/1224
Please consider the following program: import std.stdio; struct A { int opApply( scope int delegate(int) dg ) { foreach(int i; 0 .. 50) { try { int res = dg(i); if( res!=0 ) { writefln("Delegate returned %s", res); return res; } } catch(Exception ex) { writefln("Caught in loop: %s", ex.msg); } } return 0; } } void main() { try { A a; foreach(i; a) { writefln("Loop got %s", i); if( i==10 ) { throw new Exception("Excccption"); } if( i==20 ) { break; } } } catch( Exception ex ) { writefln("Caught outside of loop: %s", ex.msg); } } When run, I expected the loop to break after 10 iterations due to the exception being thrown. Instead, the loop continued. The problem with this is that, sometimes, the task generating the loop might, itself, require exception handling. Distinguishing between the exceptions thrown inside the delegate and outside it becomes a somewhat tricky exercise. At the very least, I think this behaviour should be documented. Thoughts? Shachar
Feb 02 2016
It seems this is a natural consequence of the lowering. As such, I'm not surprised by the behaviour, of course under the assumption I - as an end user - actually know that the given opApply catches the exception. I guess there could be a recommendation in opApply's specification that implementors shouldn't needlessly catch exceptions, especially not unspecific ones like `Exception`, but if they do, they should rethrow them, or better yet use scope(exit/finally) and try/finally as appropriate.
Feb 02 2016
On 2/2/16 4:44 AM, Shachar Shemesh wrote:Please consider the following program: import std.stdio; struct A { int opApply( scope int delegate(int) dg ) { foreach(int i; 0 .. 50) { try { int res = dg(i); if( res!=0 ) { writefln("Delegate returned %s", res); return res; } } catch(Exception ex) { writefln("Caught in loop: %s", ex.msg); } } return 0; } } void main() { try { A a; foreach(i; a) { writefln("Loop got %s", i); if( i==10 ) { throw new Exception("Excccption"); } if( i==20 ) { break; } } } catch( Exception ex ) { writefln("Caught outside of loop: %s", ex.msg); } } When run, I expected the loop to break after 10 iterations due to the exception being thrown. Instead, the loop continued. The problem with this is that, sometimes, the task generating the loop might, itself, require exception handling. Distinguishing between the exceptions thrown inside the delegate and outside it becomes a somewhat tricky exercise. At the very least, I think this behaviour should be documented. Thoughts?Just put try around the opApply specific parts you want to monitor. Don't guard the call to dg. -Steve
Feb 02 2016
On 02/02/16 17:00, Steven Schveighoffer wrote:Just put try around the opApply specific parts you want to monitor. Don't guard the call to dg.The call to dg is, obviously, part of a loop. That whole loop body is inside a try/catch. What I ended up doing, instead, was to put a flag, and the call to dg is, effectively: stuff... { scope(failure) flags=true; dg(); } more stuff... and then, the catch: catch(Exception ex) { if( flags ) throw ex; other stuff... } My problem isn't so much the actual how to solve it, but rather that it is a potential pitfall when implementing that I don't think is documented. Shachar
Feb 02 2016
On 2/2/16 10:21 AM, Shachar Shemesh wrote:On 02/02/16 17:00, Steven Schveighoffer wrote:I don't see a big difference from this: int opApply( scope int delegate(int) dg ) { foreach(int i; 0 .. 50) { int res = dg(i); try { if( res!=0 ) { writefln("Delegate returned %s", res); return res; } } catch(Exception ex) { writefln("Caught in loop: %s", ex.msg); } } return 0; }Just put try around the opApply specific parts you want to monitor. Don't guard the call to dg.The call to dg is, obviously, part of a loop. That whole loop body is inside a try/catch.My problem isn't so much the actual how to solve it, but rather that it is a potential pitfall when implementing that I don't think is documented.OK, I understand what you are saying. It could be listed in the docs as something to avoid. -Steve
Feb 02 2016
On 02/02/2016 07:21 AM, Shachar Shemesh wrote:it is a potential pitfall when implementing that I don't think is documented.Good catch! Please either open a documentation bug for this or fork the repo and fix it yourself. :) (Hopefully, there is an 'Improve this page' link on that page.) Ali
Feb 02 2016
On 02/02/16 21:24, Ali Çehreli wrote:On 02/02/2016 07:21 AM, Shachar Shemesh wrote: > it is a potential pitfall when implementing that I don't think is > documented. Good catch! Please either open a documentation bug for this or fork the repo and fix it yourself. :) (Hopefully, there is an 'Improve this page' link on that page.) Alihttps://github.com/D-Programming-Language/dlang.org/pull/1224
Feb 03 2016