digitalmars.D.learn - Is there a way to do the same thing in entry and return of a bunch of
- Stefanos Baziotis (65/65) Sep 17 2019 I think it's better to give a concrete example rather than
- Nicholas Wilson (16/33) Sep 17 2019 I think a mixin that does
- Stefanos Baziotis (9/23) Sep 18 2019 Yes that's what I meant sort of the mixin (where we can also put
I think it's better to give a concrete example rather than explaining this vaguely. - For those who are familiar with LDC internals: I want to create something like LOG_SCOPE. You can skip the explanation. - For those who are not: Imagine that you want to track down how deep in the call stack you are, so that you can print nice log messages. That is, if you have: func3() { debug_log("message in func3"); } func2() { debug_log("message in func2"); func3(); debug_log("message in func2"); } func1() { func2(); } main() { func1(); } In this case, I'd like to have something like this: * * message in func 2 * * * message in func3 * * message in func2 So, we could create a global variable CALL_DEPTH or smth, and in every function right at the beginning, do: CALL_DEPTH += 1; and in the end: CALL_DEPTH -= 1; And then implement debug_log as (skipping the printf-like things etc.): for (int i = 0; i != CALL_DEPTH; ++i) printf("* "); But the thing is, now we have to put the += and -= in every function, when it is really common in all of them and there's no reason to be visible anyway. LDC does something that IMO is ingenious. It's something like (it's C++): #define LOG_SCOPE LoggerObj _logscope; But LoggerObj has a constructor that does the += and the destructor that does -=. So, you can put just one line of: LOG_SCOPE; at any point inside a function and the desired thing is done almost invisibly. -- The question -- Can we do better ? For one, I believe that because D does not have a preprocessor, we have to do an actual declaration which would be somewhat more verbose. Or do a mixin that does it. mixin can help as it can be more complicated and also we can access local scope (although I don't think this is a good idea). But in both cases, they're not totally invisible. Can we do something like: func1, func2 and func3, when they enter do the X and when they return, they do the Y. Thanks, Stefanos
Sep 17 2019
On Tuesday, 17 September 2019 at 17:11:09 UTC, Stefanos Baziotis wrote:I think it's better to give a concrete example rather than explaining this vaguely. -- The question -- Can we do better ? For one, I believe that because D does not have a preprocessor, we have to do an actual declaration which would be somewhat more verbose. Or do a mixin that does it. mixin can help as it can be more complicated and also we can access local scope (although I don't think this is a good idea). But in both cases, they're not totally invisible. Can we do something like: func1, func2 and func3, when they enter do the X and when they return, they do the Y. Thanks, StefanosI think a mixin that does string LOG_SCOPE = q{ callDepth++; scope(exit) callDepth--; } is probably the easiest. for bonus points string LOG_SCOPE = q{ callDepth++; debug_log(__FUNCTION__);// or __PRETTY_FUNTION__ scope(exit) callDepth--; } and the mixin(LOG_SCOPE); I mean you _could_ do some UDA reflection to generate wrapping function that do the indentation, bit that is overkill.
Sep 17 2019
On Wednesday, 18 September 2019 at 01:03:27 UTC, Nicholas Wilson wrote:I think a mixin that does string LOG_SCOPE = q{ callDepth++; scope(exit) callDepth--; } is probably the easiest. for bonus points string LOG_SCOPE = q{ callDepth++; debug_log(__FUNCTION__);// or __PRETTY_FUNTION__ scope(exit) callDepth--; } and the mixin(LOG_SCOPE);Yes that's what I meant sort of the mixin (where we can also put local scope inside etc.).I mean you _could_ do some UDA reflection to generate wrapping function that do the indentation, bit that is overkill.Interesting, I didn't know about that. I didn't completely get it but I get that it seems the easier way to do it is the mixin. Thanks, Stefanos
Sep 18 2019