Avoid mess with code debugging

When I write something, half the effort tends to make clear and concise debug output or functionality that can be turned on / off when something needs debugging.

An example of a debugging function is the bootloader class, in which I can include #define, which causes it to โ€œpretendโ€ to load the file and just pass me the one I already have. Thus, I can check what happens when the user downloads the file, without waiting for the network to physically capture the file each time. This is great functionality, but the code is getting more messy with C # ifdefs.

I end up with a bunch of #define like

 // #define DEBUG_FOOMODULE_FOO // #define DEBUG_BARMODULE_THINGAMAJIG // ... 

which are uncommented for the material I want to look at. The code itself is something like

 - (void)something { #ifdef DEBUG_FOOMODULE_FOO DebugLog(@"something [x = %@]", x); #endif // ... #ifdef DEBUG_FOOMODULE_MOO // etc } 

This works great for writing / maintaining code, but does nothing for the appearance of code.

How do people write effortlessly on-the-fly debugging material anyway?

Note. I'm not just talking about NSLogging here ... I am also talking about things like pretend-download above.

+6
source share
3 answers

I read several libraries before writing my own and saw two approaches: macro + C functions ( NSLogger ) or macro + Singleton ( GTMLogger , Cocoa Lumberjack ).

I wrote my naive implementation here using the + singleton macro. I do this at runtime:

 [Logger singleton].logThreshold = kDebug; trace(@"hi %@",@"world); // won't show debug(@"hi %@",@"world); 

You can do the same for packages, not log levels. If I want it to disappear, I changed #defines. Here is the code:

 #define trace(args...) [[Logger singleton] debugWithLevel:kTrace line:__LINE__ funcName:__PRETTY_FUNCTION__ message:args]; if (level>=logThreshold){ // ... } 

If you need a more sophisticated look at Lumberjack, it has a register class tool for switching logs for some classes.

+2
source

Having two functions, then select them accordingly either at runtime or when compiling seems like a clean approach to me. This allows you to have one download.c and one download_debug.c file with the same functions, with the exception of different implementations. Then contact the appropriate one if you are building with -DDEBUG or not.

Otherwise, using function pointers also works for runtime selection functions.

If you insist that the debugging code is interspersed in all your functions, you pretty much set yourself up for a mess :) But you can, of course, break these fragments into separate functions and then do it higher (or make them different than in the example DLog).

+1
source

In your case, you can have separate logging macros, say MooLog and FooLog , which all are conditionally compiled based on individual flags.

 #ifdef DEBUG_FOO # define FooLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #else # define FooLog(...) #endif #ifdef DEBUG_MOO # define MooLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #else # define MooLog(...) #endif 

Now your complex logic becomes the following:

 - (void)something { // This only gets logged if the "DEBUG_FOO" flag is set. FooLog(@"something [x = %@]", x); // This only gets logged if the "DEBUG_MOO" flag is set. MooLog(@"Something else [y = %@]", y); } 
0
source

Source: https://habr.com/ru/post/893157/


All Articles