Modules. What are they!?
Modules. What are they!?
Hi,
Now before I get flamed, I did do a search of the forums for Modules but found the topics too advanced for my poor brain and couldn't find anything that gave me any enlightenment!
So can someone please explain to me (like I'm an idiot) :
What is a module?
Why should I use them?
How do I use them?
and then a basic example of what they allow us to do now...
I may have a nice ripe apple to give the person who can make me understand them.
Thanks in advance!
Now before I get flamed, I did do a search of the forums for Modules but found the topics too advanced for my poor brain and couldn't find anything that gave me any enlightenment!
So can someone please explain to me (like I'm an idiot) :
What is a module?
Why should I use them?
How do I use them?
and then a basic example of what they allow us to do now...
I may have a nice ripe apple to give the person who can make me understand them.
Thanks in advance!
----
R Tape loading error, 0:1
R Tape loading error, 0:1
Re: Modules. What are they!?
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
-
- Addict
- Posts: 1520
- Joined: Wed Nov 12, 2008 5:01 pm
- Location: Russia
Re: Modules. What are they!?
@em_uk: Thank you for the question. I'm having problems with Modules.
@WilliamL: Thank you for the link. I must have missed that one.

@WilliamL: Thank you for the link. I must have missed that one.

DE AA EB
Re: Modules. What are they!?
I'm trying to figure it out myself, so let me see if I've got it right. If not, please steer me in the right direction.
In its simplest form, this is the basic structure of a module:At this point, they do absolutely nothing, so let's begin by adding a simple variable:The module now contains an integer variable, a, assigned with a value of 1. Since it is defined within the module space, it is a private variable, accessible only within the module. To add a public variable, it has to be defined in the module declaration, like this:The integer variable a is now a public variable that is accessible inside and outside the module. Similarly, constants and procedures can also be private or public, depending on where they are declared. It should be noted that public variables can still be manipulated within the module:As mentioned earlier, constants can also be defined within the module, either as private or public ones, depending on where they are defined:Here, constant1 is a public constant, while constant2 is a private constant. Procedures, on the other hand, should always be created within the module, but to declare them as public, an additional declaration is required:At this point, the procedure test() is a private procedure, accessible only within the module space. To make it a public procedure, accessible from outside the module, it has to also be declared in the module declaration:The procedure test()is now a public procedure, accessible from both inside and outside the module. Another procedure is added here to demonstrate this:Here, a new private procedure, test2(), calls the public procedure test(), making use of both private as public constants as well. Note that the procedure test2() is private only because it has not been declared in the module declaration, and can be made public by simply doing so.
Now, to use the module. As mentioned earlier, only public constants, variables and procedures are accessible from outside the module. This can be done in two ways. The first method is to use the full name of the module, in this case myModule, followed by two colons (::), and then the name of the public constant, variable or procedure:The second method is by using the keyword UseModule followed by the module name, myModule. After that, the public constants, variables and procedures can be used directly without any prefixes:The keyword UseModule essentially merges the module namespace with the global namespace. It works in a similar way as the With/EndWith function, but without the need for the backslash (\) or EndWith. To stop this namespace merger, simply call UnuseModule, followed by the module name:This stops the namespace merger, and any further calls to the module must be done either with the full module name with double colons, or by calling the UseModule function with the module name again. One important point regarding namespaces: when using the UseModule function, the global namespace cannot contain same-named constants, variables or procedures. The following code syntax is legal:This code syntax is not legal, and will raise an "...already declared in global scope" error:However, if no name conflicts are expected, the UseModule function is very useful, and can save a lot of typing. Simply place it at the beginning of the program code, just after the module declaration:
It should also be noted that, unlike procedures, the global contents in the module space are executed even if the module is not called. To illustrate:Clearly, even if the above procedure was placed at the beginning of the program code, the debug statement would not be executed unless the procedure is called.On the other hand, if the above module was placed at the beginning of the program code, although the first debug statement would not be executed, the second one would.
So, that's PureBasic's new module function in a nutshell. Its main advantage over DLLs, procedures and include files is its unique namespace feature. Having a totally separate namespace allows modules to have constants, variables and procedures that would not run the risk of name conflicts, while still being able to share and expose selected elements, and have its code accessible from within the IDE.
Here's the complete working code for this little tutorial:Feedback and corrections are appreciated. 
In its simplest form, this is the basic structure of a module:
Code: Select all
DeclareModule myModule
;this is called the module declaration
EndDeclareModule
Module myModule
;this is called the module space
EndModule
Code: Select all
DeclareModule myModule
EndDeclareModule
Module myModule
Define a.i = 1
EndModule
Code: Select all
DeclareModule myModule
Define a.i = 1
EndDeclareModule
Module myModule
EndModule
Code: Select all
DeclareModule myModule
Define a.i = 1
EndDeclareModule
Module myModule
a = 2
EndModule
Code: Select all
DeclareModule myModule
#constant1 = 100
Define a.i = 1
EndDeclareModule
Module myModule
#constant2 = 200
a = 2
EndModule
Code: Select all
DeclareModule myModule
#constant1 = 100
Define a.i = 1
EndDeclareModule
Module myModule
#constant2 = 200
a = 2
Procedure test(param)
ProcedureReturn param + #constant1
EndProcedure
EndModule
Code: Select all
DeclareModule myModule
#constant1 = 100
Define a.i = 1
Declare test(param)
EndDeclareModule
Module myModule
#constant2 = 200
a = 2
Procedure test(param)
ProcedureReturn param + #constant1
EndProcedure
EndModule
Code: Select all
DeclareModule myModule
#constant1 = 100
Define a.i = 1
Declare test(param)
EndDeclareModule
Module myModule
#constant2 = 200
a = 2
Procedure test(param)
ProcedureReturn param + #constant2
EndProcedure
Procedure test2(param)
ProcedureReturn test(param) + #constant1
EndProcedure
EndModule
Now, to use the module. As mentioned earlier, only public constants, variables and procedures are accessible from outside the module. This can be done in two ways. The first method is to use the full name of the module, in this case myModule, followed by two colons (::), and then the name of the public constant, variable or procedure:
Code: Select all
Debug myModule::#constant1 ;returns 100
Debug myModule::a ;returns 2
Debug myModule::test(22) ;returns 222
Code: Select all
UseModule myModule
Debug #constant1 ;returns 100
Debug a ;returns 2
Debug test(22) ;returns 222
Code: Select all
UseModule myModule
Debug #constant1
Debug a
Debug test(22)
UnuseModule myModule
Code: Select all
#constant1 = "Hello"
Define a.f = 1.23
Procedure.s test()
ProcedureReturn #constant1 + " World!"
EndProcedure
Debug myModule::#constant1 ;returns 100
Debug myModule::a ;returns 2
Debug myModule::test(22) ;returns 222
Debug #constant1 ;returns "Hello"
Debug a ;returns 1.23
Debug test() ;returns "Hello World!"
Code: Select all
#constant1 = "Hello"
Define a.f = 1.23
Procedure test()
Debug #constant1 + " World!"
EndProcedure
UseModule myModule ;raises error
Debug #constant1
Debug a
Debug test(22)
UnuseModule myModule
Code: Select all
DeclareModule myModule
#constant1 = 100
Define a.i = 1
Declare test(param)
EndDeclareModulee
UseModule myModule
;the rest of the program code
;UnuseModule not required...
Code: Select all
Procedure someProcedure()
Debug "I will not be executed..."
EndProcedure
Code: Select all
DeclareModule someModule
EndDeclareModule
Module someModule
Procedure test(param)
Debug "I will not be executed..."
EndProcedure
Debug "I will be executed..."
EndModule
So, that's PureBasic's new module function in a nutshell. Its main advantage over DLLs, procedures and include files is its unique namespace feature. Having a totally separate namespace allows modules to have constants, variables and procedures that would not run the risk of name conflicts, while still being able to share and expose selected elements, and have its code accessible from within the IDE.
Here's the complete working code for this little tutorial:
Code: Select all
DeclareModule myModule
#constant1 = 100
Define a.i = 1
Declare test(param)
EndDeclareModule
Module myModule
#constant2 = 200
a = 2
Debug "This line will be executed..."
Procedure test(param)
ProcedureReturn param + #constant2
EndProcedure
Procedure test2(param)
ProcedureReturn test(param) + #constant1
EndProcedure
EndModule
;----------------------------------------
;UseModule works here before same-named
;constants, variables and procedures are
;declared in the global namespace
;----------------------------------------
UseModule myModule
Debug #constant1 ;returns 100
Debug a ;returns 2
Debug test(22) ;returns 222
UnuseModule myModule
;----------------------------------------
#constant1 = "Hello"
Define a.f = 1.23
Procedure.s test()
ProcedureReturn #constant1 + " World!"
EndProcedure
Debug myModule::#constant1 ;returns 100
Debug myModule::a ;returns 2
Debug myModule::test(22) ;returns 222
Debug #constant1 ;returns "Hello"
Debug a ;returns 1.23
Debug test() ;returns "Hello World!"
;----------------------------------------
;UseModule fails here because same-named
;constants, variables and procedures have
;been declared in the global namespace
;and are conflicting with the module's
;constants, variables and procedures.
;----------------------------------------
; UseModule myModule
; Debug #constant1
; Debug a
; Debug test(22)
; UnuseModule myModule
;----------------------------------------

Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

Re: Modules. What are they!?
Thank you all for the links and especially TI-994A for that indepth opener. I think I am starting to get it.
So how would this work with things like sprites/screens/windows?
Could I take a sinus scrolly program and then convert it to module use and then incorporate with another program, maybe a background effect and then they both output to the same screen/window?
I will have a little go and see if I have grasped it.

So how would this work with things like sprites/screens/windows?
Could I take a sinus scrolly program and then convert it to module use and then incorporate with another program, maybe a background effect and then they both output to the same screen/window?
I will have a little go and see if I have grasped it.

----
R Tape loading error, 0:1
R Tape loading error, 0:1
Re: Modules. What are they!?
just wondering about the use of UnuseModule - why does it have a parameter?
unless this is legal syntax:
it would seem to make more sense and would be neater (plus it would fit with existing PB keyword pairs) to use
unless this is legal syntax:
Code: Select all
UseModule myFirstModule
;do stuff
UseModule mySecondModule
;do more stuff
UnuseModule myFirstModule
UnuseModule mySecondModule
Code: Select all
UseModule myFirstModule
;do stuff
UseModule mySecondModule
;do more stuff (nested within the first module)
UnuseModule
UnuseModule
there is no sig, only zuul (and the following disclaimer)
WARNING: may be talking out of his hat
WARNING: may be talking out of his hat
Re: Modules. What are they!?
@citystate
UnuseModule is optional. In your second example must be called.
UnuseModule is optional. In your second example must be called.
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
Re: Modules. What are they!?
Hello citystate. As far as I know, the flow is perfectly legal, as long as there aren't any naming conflicts between the two modules. The UnuseModule directive is optional, unless needed.citystate wrote:just wondering about the use of UnuseModule - why does it have a parameter? unless this is legal syntax:Code: Select all
UseModule myFirstModule ;do stuff UseModule mySecondModule ;do more stuff UnuseModule myFirstModule UnuseModule mySecondModule
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

Re: Modules. What are they!?
Hello c4s. You're right about UnuseModule being optional, although it is still not a requirement in citystate's second example. Referring to the code in question:c4s wrote:UnuseModule is optional. In your second example must be called.
Code: Select all
UseModule myFirstModule
;do stuff
UseModule mySecondModule
;do more stuff (nested within the first module)
UnuseModule ;must include module name
UnuseModule ;must include module name
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 

-
- User
- Posts: 69
- Joined: Tue Sep 16, 2008 6:11 am
- Location: ger
Re: Modules. What are they!?
Just a small question. How to make these examples work? Booth examples won't compile..
1)
2)
I understand this has something to do with the namespace, so - how to access the "main" namespace?
Thank you!
1)
Code: Select all
#XPATH = "C:\Test\Test\Test\"
DeclareModule foo
#EXT_PATH = #XPATH + "foo.bar"
Declare.s foo()
EndDeclareModule
Module foo
Procedure.s foo()
ProcedureReturn #EXT_PATH
EndProcedure
EndModule
Code: Select all
Procedure DummyT(a.i,b.i)
ProcedureReturn a.i + b.i * 2
EndProcedure
DeclareModule bar
Declare.i bar(a.i,b.i,c.i)
EndDeclareModule
Module bar
Procedure.i bar()
ProcedureReturn DummyT(a.i,b.i) * c.i
EndProcedure
EndModule
Thank you!
-
- Addict
- Posts: 1520
- Joined: Wed Nov 12, 2008 5:01 pm
- Location: Russia
-
- Enthusiast
- Posts: 542
- Joined: Tue Apr 24, 2012 5:08 pm
- Location: Ontario, Canada
Re: Modules. What are they!?
I would highly recommend that all data be private to the module.TI-994A wrote: To add a public variable, it has to be defined in the module declaration, like this:The integer variable a is now a public variable that is accessible inside and outside the module.Code: Select all
DeclareModule myModule Define a.i = 1 EndDeclareModule Module myModule EndModule
The whole point of using modules is to isolate the code from the rest of the application. If data is made freely available then the resulting spaghetti code is guaranteed to cause problems. Module data, if needed, should only be accessed via public procedures. This is particularly important if one hopes to use a module in many applications. An application should not need to know how the module data is structured.
I would also recommend that the UseModule/UnuseModule feature not be used. It removes clarity from the code and is a good way to introduce bugs. A well structured application doesn't need to use this feature.
Modules should be treated as "black boxes", and are best used for large blocks of related code. Lots of "public" data, and heavy use of the UseModule feature, means that the modules are fragmented and need to be combined in a way that will simplify the overall structure of the application.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
~ Spike Milligan
-
- User
- Posts: 69
- Joined: Tue Sep 16, 2008 6:11 am
- Location: ger
Re: Modules. What are they!?
@User_Russian: Thank you for the link!
Black Box or not, this behavior is rather strange im my opinion.
So now I have to do a workarround like this in order to get it working correctly - more typing than necessary:
Why can't we have a global namespace to access?
Black Box or not, this behavior is rather strange im my opinion.
So now I have to do a workarround like this in order to get it working correctly - more typing than necessary:
Code: Select all
DeclareModule GlobalConst
#XPATH = "C:\Test\Test\Test\"
EndDeclareModule
DeclareModule foo
#EXT_PATH = GlobalConst::#XPATH + "foo.bar"
Declare.s foo()
EndDeclareModule
Module foo
Procedure.s foo()
ProcedureReturn #EXT_PATH
EndProcedure
EndModule
Debug foo::foo()
Re: Modules. What are they!?
Hello Deluxe0321. Both the examples fail because the modules were trying to access constants and procedures that are outside their scope. In the second example, the procedure declaration did not match the procedure itself. Here's the working code:Deluxe0321 wrote:Just a small question. How to make these examples work? Booth examples won't compile..
Code: Select all
;the constant #XPATH is in the global
;namespace and is not accessible to modules
#XPATH = "C:\Test\Test\Test\"
DeclareModule foo
;removing the reference works
;#EXT_PATH = #XPATH + "foo.bar"
#EXT_PATH = "foo.bar"
Declare.s foo()
EndDeclareModule
Module foo
Procedure.s foo()
ProcedureReturn #EXT_PATH
EndProcedure
EndModule
Debug foo::foo() ;returns foo.bar
Code: Select all
;the procedure DummyT() is in the global
;namespace and is not accessible to modules
Procedure DummyT(a.i,b.i)
ProcedureReturn a.i + b.i * 2
EndProcedure
DeclareModule bar
;here bar() is declared with parameters
Declare.i bar(a.i,b.i,c.i)
EndDeclareModule
Module bar
;here bar() does not have any parameters
;Procedure.i bar()
Procedure.i bar(a.i,b.i,c.i)
ProcedureReturn a + b + c
;DummyT() is not accessible from here
;ProcedureReturn DummyT(a.i,b.i) * c.i
EndProcedure
EndModule
Debug bar::bar(1, 2 ,3) ;returns 6
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel 
