digitalmars.D - Return in finally
- Frank Benoit (keinfarbton) (23/23) Mar 07 2007 While programatically porting Java ...
- BCS (26/55) Mar 07 2007 try
- Frank Benoit (keinfarbton) (40/40) Mar 07 2007 If i understand your idea right...
- Frank Benoit (keinfarbton) (30/30) Mar 07 2007 // D ==========================
- BCS (4/16) Mar 07 2007 There is no need for special excption types, Object will catch
- Ary Manzana (61/64) Mar 07 2007 Maybe you can do something like this:
- Frank Benoit (keinfarbton) (36/37) Mar 07 2007 yes, this would handle the return, but it would not allow a second
While programatically porting Java ... A finally block cannot contain another try/catch block. This is allowed in Java. The solution i use is this: int f(){ try{ } finally { (){ // start definition of an unnamed function literal try{ } finally { // (1) } }(); // call it. } return 1; } Now, i have the first time the situation where at (1) a return statement occurs. This is not allowed in an a finally block at all [2], and withing the function literal it would not end the surrounding function. Any idea, how to simulate 1.) try/catch/finally in a finally 2.) make a return from within a finally ?? [2] not allowed in D, but it is allowed in Java
Mar 07 2007
Frank Benoit (keinfarbton) wrote:While programatically porting Java ... A finally block cannot contain another try/catch block. This is allowed in Java. The solution i use is this: int f(){ try{ } finally { (){ // start definition of an unnamed function literal try{ } finally { // (1) } }(); // call it. } return 1; } Now, i have the first time the situation where at (1) a return statement occurs. This is not allowed in an a finally block at all [2], and withing the function literal it would not end the surrounding function. Any idea, how to simulate 1.) try/catch/finally in a finally 2.) make a return from within a finally ?? [2] not allowed in D, but it is allowed in Javatry { ... } finally { ... return; ... } | | v try { ... } catch(Object e) { ... return; ... throw e; } bad practice in hand work, but this is auto gen code.
Mar 07 2007
If i understand your idea right... class FinallyException : Object {} // Special excecption to enter a finally block. class Throwable : Exception {} // Base of all Java Exceptions Now, instead of finally use only catch blocks catch( FinallyException fe ){ ... } Hm, i need to think more about it... The FinallyException can be used to transport a thrown exception At (1),(2) and (3) a return(val) or throw can happen. // Java ========================== try{ // (1) } catch( IOException e ){ // (2) } finally { // (3) } // D ========================== auto fe = new FinallyException(); try{ try{ // (1) throw fe; } catch( IOException e ){ try{ // (2) } catch( Object e ) { fe.store(e); throw fe; } } }catch( FinallyException fe ){ // (3) } fe.throwIfHasException(); Does this work? oh, my brain hurts :) Another thought, what about the performance, if an exception is always thrown to reach the "finally" block? is that an issue?
Mar 07 2007
// D ========================== int func(){ ... { Tioport_ResultState!(int) tioport_result_001; try{ try{ // (1) } catch( IOException e ){ // (2) } } catch( Object e ) { // catch and store for rethrow after Finally_001 tioport_result_001.setException( e ); } Finally_001: { // (3) } tioport_result_001.checkException(); // throw if one was stored return tioport_result_001.get(); } } In (1) und (2) replace all "return;" with "goto Finally_001;". "return expr;" with "{ tioport_result_001.set( expr ); goto Finally_001; }" If in (3) a return or throw occurs, it hides previous returns/throws, like java does. This approach do not throw an exception in normal run. What do you think? Do I miss a less complicated way?
Mar 07 2007
Frank Benoit (keinfarbton) wrote:If i understand your idea right... class FinallyException : Object {} // Special excecption to enter a finally block. class Throwable : Exception {} // Base of all Java Exceptions Now, instead of finally use only catch blocks catch( FinallyException fe ){ ... }There is no need for special excption types, Object will catch everything. Err. However it won't catch a normal exit. Fud, It's not quite as clean as I thought.
Mar 07 2007
Frank Benoit (keinfarbton) escribió:Any idea, how to simulate 2.) make a return from within a finally ??Maybe you can do something like this: Java ------------------------------------------------- int func() { try { } finally { return 1; } } ------------------------------------------------- D ------------------------------------------------- import std.boxer; int func() { Box finallyReturn; try { } finally { finallyReturn = box(1); } if (finallyReturn.type !is null) { return unbox!(int)(finallyReturn); } } ------------------------------------------------- You have to be careful, though. After every block that has a return statement you have to proceed only if the box's type is null. For example: Java ------------------------------------------------- int func() { try { } finally { if (someCondition) { return 1; } doSomeStuff(); return 2; } } ------------------------------------------------- D ------------------------------------------------- import std.boxer; int func() { Box finallyReturn; try { } finally { if (someCondition) { finallyReturn = box(1); } if (finallyReturn.type is null) { doSomeStuff(); finallyReturn = box(2); } } if (finallyReturn.type !is null) { return unbox!(int)(finallyReturn); } } ------------------------------------------------- Does this work?
Mar 07 2007
Does this work?yes, this would handle the return, but it would not allow a second try/catch in the finally block. What i use now is this: // D ========================== int func(){ ... { bool tioport_stat_set_1; int tioport_stat_val_1; Object tioport_stat_exc_1; try{ try{ // (1) tryend_1:; } catch( IOException e ){ // (2) } catchend_1:; } catch( Object e ) { tioport_stat_exc_1 = e; } { // (3) } if(tioport_stat_exc_1 !is null) throw tioport_stat_exc_1; if(tioport_stat_set_1) return tioport_stat_val_1; } } In (1) und (2) replace all "return expr;" with { tioport_stat_set_1 = true; tioport_stat_val_1 = expr; // if has a return val goto tryend_1; // or catchend_1 } Now the finally block is a normal code block. It is possible to have more try/catch in the finally block. It is possible to return/throw from the finally block
Mar 07 2007