Do you have to make the library user create a module definition, and if he doesn't because he just wants to use the defaults ?
Please look below.
I've put together an example:
library.pb
Code: Select all
CompilerIf Defined(lib_config_1, #PB_Constant) = 0
#lib_config_1 = 1 ; default
CompilerEndIf
CompilerIf Defined(lib_config_2, #PB_Constant) = 0
#lib_config_2 = 1 ; default
CompilerEndIf
CompilerIf Defined(lib_config_3, #PB_Constant) = 0
#lib_config_3 = 0 ; default
CompilerEndIf
Procedure proc()
; common code start
CompilerIf #lib_config_1 = 0
; some code
CompilerElse
;other code
CompilerEndIf
CompilerIf #lib_config_3 = 1
; some code
CompilerEndIf
; common code end
EndProcedure
user_program.pb
Code: Select all
#lib_config_1 = 0
#lib_config_2 = 0
#lib_config_3 = 1
; the constants above customize the library include that follows
Includefile "library.pb"
proc()
As I've explained in the other message to Lucifer[SD] the library checks if the constants are defined, use what it finds defined and defines what's not by setting it to default values.
The user of the library, before including it, set some, none, or all the desired constant in order to customize the library compilation.
Neat. Easy to use, easy to follow, easy to implement.
Now, let's try to convert the lib to a module.
library.pb
Code: Select all
DeclareModule lib
Declare proc()
EndDeclareModule
Module lib
CompilerIf Defined(lib_config_1, #PB_Constant) = 0
#lib_config_1 = 1 ; default
CompilerEndIf
CompilerIf Defined(lib_config_2, #PB_Constant) = 0
#lib_config_2 = 1 ; default
CompilerEndIf
CompilerIf Defined(lib_config_3, #PB_Constant) = 0
#lib_config_3 = 0 ; default
CompilerEndIf
Procedure proc()
; common code start
CompilerIf #lib_config_1 = 0
; some code
CompilerElse
;other code
CompilerEndIf
CompilerIf #lib_config_3 = 1
; some code
CompilerEndIf
; common code end
EndProcedure
EndModule
Now,
user_program.pb does not work anymore as expected. Setting the constants is useless because the module does not have access to them. If we had the ability to do so:
Code: Select all
CompilerIf Defined(::lib_config_1, #PB_Constant) = 0
#lib_config_1 = 1 ; default
CompilerEndIf
(see the "::" before the constant name) to access the top-level constants the problem would be solved.
Not having that, Freak asked me what's the problem with just defining a module with the constants declared there, like the code above from idle shows.
freak wrote:
Exactly. What is the problem with that?
Please consider my case. How do you something like that ? Do you make the user, the author of
user_program.pb replace the original code:
Code: Select all
#lib_config_1 = 0
#lib_config_2 = 0
#lib_config_3 = 1
; the constants above customize the library include that follows
Includefile "library.pb"
proc()
with this ?
Code: Select all
DeclareModule lib_consts
#lib_config_1 = 0
#lib_config_2 = 0
#lib_config_3 = 1
EndDeclareModule
; the constants above customize the library include that follows
Includefile "library.pb"
proc()
and inside
library.pb I use
UseModule lib_consts ?
But what if the user does not want to define those constants ? If he doesn't the compiler raise an error on
UseModule lib_consts because the module is not defined.
1) Having "Defined" supporting testing for modules I could test if the module lib_consts is defined and if it's not I could define it with the default constants. But this is not available for now. Even so the it would be already a lot less easy to follow compared to the plain original version.
2) The ::#Const_Name to access a top level constant is also not available, and that would be the best solution for this case I believe.
idle wrote:
Though I don't see why it can't check the context of the module for a constant and if it's not found in that scope
check the global scope for the constant
or probably better because it's explicit the nameless module "::nameofconst", so we don't risk to access a top-level constant in error.
3) I must tell the user to define an empty DeclareModule lib_consts if he doesn't want to override the defaults ?
Looks like a silly thing to ask compared to the original module-less solution where he had to do nothing at all.
I feel like I'm moving away from a clean solution based on simple constants towards something unnecessary convoluted.
Well, something easily avoidable with at least one of the additions above.
Considering what's available, can I solve this in a manner somewhat equivalent to the original one ?