For the project I'm currently working on, I've found a very useful way to use the PureBasic compiler function 'Defined()'.
I wanted to share that with you, perhaps this will give you other ideas as well to use this very powerful feature of PureBasic.
For my project I've implemented a hierarchical logging system. Basically it allows to have a hierarchical view of which classes/procedures have been visited and from exactly where each log message has been produced and in which context.
Normally, to implement this in C++, you use a simple local object on the stack. When it is created (constructor called) it send a 'Log.Enter()' signal/message/call to the logging system, and when this object leave the scope of the procedure, the destructor is called and send a 'Log.Leave()' signal/message/call to the logging system. In between you use this object to log messages.
This is pretty automatic, you don't have to worry about the life time of this local object nor it's hierarchical nature/management.
In C, you have to do this manually whenever you leave your procedure. At each 'exit point' of your procedure you have to call for 'Log_Leave()'.
In PureBasic you have to do the same. But, thanks to this Defined() compiler function, you can bring back the automatic management of 'scope destructor' with the help of some macros too.
Code: Select all
Procedure.i MyProc()
LOG_ENTER()
Protected my_result.i = 0
; ../..
ret( my_result )
EndProcedure
Then the ret() macro is defined this way:
Code: Select all
Macro ret( r )
CompilerIf Defined( log_args, #PB_Variable )
LogLeave()
CompilerEndIf
ProcedureReturn r
EndMacro
Thanks to the PureBasic 'Defined()' compiler function, I don't have to think about this anymore, it will automatically call for 'LogLeave()' whenever I exit a procedure and this, only if it 'detects' the use of the logging system through the definition of the specific local variable used by this system.
On a side note it also work for Procedures that return nothing, I use a ret( void ) macro for this, 'void' being defined as nothing.
This is very practical and in my case it simulates the automatic C++ scope destructor of local objects.