digitalmars.D.learn - How to do conditional scope(exit) ?
- John Dougan (44/44) Dec 18 As the subject. The obvious way:
- monkyyy (3/8) Dec 18 I dont think its anywhere near that smart, ive never seen a
- Jonathan M Davis (71/113) Dec 18 scope statements are run when the scope that they're in exits (with
- mzfhhhh (30/36) Dec 18 This code can make "scope exit 2" be output at the end.
- kdevel (32/37) Dec 19 ```
As the subject. The obvious way: ```D import std; int test(int val) { writeln("A"); if (val % 2 == 0) { writeln("b"); scope (exit) writeln("scope exit ", val); writeln("c"); } writeln("F"); return 2 * val; } void main() { writeln("== start ========================="); int v1 = test(1); writeln("== 2 =============================="); int v2 = test(2); writeln("== end ==========================="); } ``` results in: ``` == start ========================= A F == 2 ============================== A b c scope exit 2 F == end =========================== ``` which isn't what I want. The case for `test(1)` is fine. For `test(2))` I want the `scope exit 2` to come after the `F`. Is there a way to tell it that I want to use an enclosing scope or make it ignore the scope on the `if`? Cheers, -- John
Dec 18
On Wednesday, 18 December 2024 at 22:16:45 UTC, John Dougan wrote:Is there a way to tell it that I want to use an enclosing scope or make it ignore the scope on the `if`? Cheers, -- JohnI dont think its anywhere near that smart, ive never seen a single usecase of scope(exit) do anything of note
Dec 18
On Wednesday, December 18, 2024 3:16:45 PM MST John Dougan via Digitalmars-d-learn wrote:As the subject. The obvious way: ```D import std; int test(int val) { writeln("A"); if (val % 2 == 0) { writeln("b"); scope (exit) writeln("scope exit ", val); writeln("c"); } writeln("F"); return 2 * val; } void main() { writeln("== start ========================="); int v1 = test(1); writeln("== 2 =============================="); int v2 = test(2); writeln("== end ==========================="); } ``` results in: ``` == start ========================= A F == 2 ============================== A b c scope exit 2 F == end =========================== ``` which isn't what I want. The case for `test(1)` is fine. For `test(2))` I want the `scope exit 2` to come after the `F`. Is there a way to tell it that I want to use an enclosing scope or make it ignore the scope on the `if`?scope statements are run when the scope that they're in exits (with scope(exit) always running, scope(failure) running only when the scope is exited via an exception being thrown, and scope(success) only being run when no exception is thrown). There is no way to control whether they run beyond whether it's exit, failure, or success, and trying to insert if statements around scope statements is just going to change which scope that they refer to, since you can't put a scope statement in an inner scope and then have it be run for an outer scope. It's always for the scope that the scope statement is in. Now, you _can_ put an if statement within the scope statement to control what's run within the scope statement, but that condition will be checked when the scope statement is run. So, you may be able to get what you want that way, but scope statements themselves are quite simple and not particularly flexible. Ultimately, they're just a way to not have to manually write a try-catch block when you don't care about actually looking at the exception being thrown and just want to write code that runs or doesn't run based on whether the scope is exited normally or via an exception being thrown. One thing to remember is that scope statements are implemented as try-catch blocks. So, if you have something like { scope(exit) doStuff(); runCode(); } it'll be lowered to something along the lines of { try { runCode(); doStuff(); } catch(Exception e) { doStuff(); throw e; } } and { scope(failure) doStuff(); runCode(); } will be lowered to something like { try { runCode(); } catch(Exception e) { doStuff(); throw e; } } whereas { scope(success) doStuff(); runCode(); } will be lowered to something like { runCode(); doStuff(); } So, when you're considering what can or can't be done with scope statements, thinking about how they're lowered to try-catch blocks may help you understand why they work the way that they do. And if you can't do what you want to do with a try-catch block, then you definitely can't do it with scope statements, since that's what they ultimately are. - Jonathan M Davis
Dec 18
On Wednesday, 18 December 2024 at 22:16:45 UTC, John Dougan wrote:As the subject. The obvious way: I want the `scope exit 2` to come after the `F`. Is there a way to tell it that I want to use an enclosing scope or make it ignore the scope on the `if`? Cheers, -- JohnThis code can make "scope exit 2" be output at the end. ```d import core.stdc.stdio; import std; enum exitcb = `scope void delegate() exitcb; scope(exit) if(exitcb) exitcb();`; int test(int val) { mixin (exitcb); writeln("A"); if (val % 2 == 0) { writeln("b"); scope (exit) exitcb = { writeln("scope exit ", val); }; writeln("c"); } writeln("F"); return 2 * val; } void main() { writeln("== start ========================="); int v1 = test(1); writeln("== 2 =============================="); int v2 = test(2); writeln("== end ==========================="); } ```
Dec 18
On Wednesday, 18 December 2024 at 22:16:45 UTC, John Dougan wrote:[...] which isn't what I want. The case for `test(1)` is fine. For `test(2))` I want the `scope exit 2` to come after the `F`.``` int test(int val) { writeln("A"); if (val % 2 == 0) { writeln("b"); scope (exit) writeln("scope exit ", val); writeln("c"); writeln("F"); } else writeln("F"); return 2 * val; } ``` results in ``` == start ========================= A F == 2 ============================== A b c F scope exit 2 == end =========================== ```Is there a way to tell it that I want to use an enclosing scope or make it ignore the scope on the `if`?Pardon, can you rephrase your question?
Dec 19