It is currently Thu Dec 12, 2019 4:24 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: PureBasic Modules: A Quick Tutorial
PostPosted: Thu May 10, 2018 6:19 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 2213
Location: Singapore
A QUICK & SIMPLE TUTORIAL ON THE USE OF MODULES

1. THE BASICS
The PureBasic manual defines modules as follows:
Quote:
Modules are an easy way to isolate code part from the main code, allowing code reuse and sharing without risk of name conflict. In some other programming languages, modules are known as 'namespaces'.

Technically, modules are mini-programs within larger programs, which could be called like procedures. But unlike procedures, they execute their immediate code without the parent program calling them. And also unlike procedures, modules could also contain their own procedures.

Let's demonstrate this with some simple examples. Consider this empty procedure:
Code:
Procedure myProcedure() 
EndProcedure

The module equivalent of the above procedure would be these set of closures:
Code:
DeclareModule myModule 
EndDeclareModule

Module myModule   
EndModule

At this point, they both do absolutely nothing. So, let's add a variable to the procedure:
Code:
Procedure myProcedure()
  Protected myVar = 123
EndProcedure

We know that the variable myVar is not accessible from the parent program, and trying to access it would only generate a new variable of the same name in the parent program, resulting with a zero value:
Code:
Procedure myProcedure()
  Protected myVar = 123
EndProcedure

Debug myVar   ; == 0

The correct way of accessing the variable in the procedure would be to instruct the procedure to deliver the value to the parent program, like so:
Code:
Procedure myProcedure()
  Protected myVar = 123
  ProcedureReturn myVar
EndProcedure

Debug myProcedure()   ; == 123

Quite simple and basic stuff.

In the case of modules, there would be two ways to add variables. This is the first way:
Code:
DeclareModule myModule
EndDeclareModule

Module myModule 
  Define myVar = 123
EndModule

And this would be the second way:
Code:
DeclareModule myModule
  Define myVar = 123
EndDeclareModule

Module myModule 
EndModule

What's the difference? Before we answer that, let's take another look at the basic structure of the module:
Code:
DeclareModule myModule 
EndDeclareModule

Module myModule   
EndModule

As the function name implies, the upper DeclareModule section handles the module declarations, while the lower Module section houses all of its functions. However, all the code in the module section would remain locked and inaccessible to the parent program unless they are selectively and expressly declared in the upper declaration section. To illustrate this further, let's return to the earlier example about the variable.

In the first of the two module examples, the variable myVar was declared in the lower module section, like so:
Code:
DeclareModule myModule
EndDeclareModule

Module myModule 
  Define myVar = 123
EndModule

Like the procedure earlier, variables in modules are also not accessible from the parent program, and trying to access them would only generate a new variable of the same name in the parent program, resulting with a zero value:
Code:
DeclareModule myModule
EndDeclareModule

Module myModule 
  Define myVar = 123
EndModule

Debug myVar   ; == 0

Unlike procedures, which would have to return the value of the variable to the parent program, variables in modules can be referenced and accessed directly. The syntax for referencing variables in modules from the parent program would be to prefix them with the module name, as follows:
Code:
DeclareModule myModule
EndDeclareModule

Module myModule 
  Define myVar = 123
EndModule

Debug myModule::myVar   ; == 0 ?

However, you'd notice that the resulting output is still zero. Why is this?

As stated earlier, variables and functions enclosed within modules are not accessible by the parent program unless they are expressly made available. And this is done by declaring them in the upper declaration section of the module structure.

In order to remedy this, and make the variable accessible, we would have to use the second method, which declares the variable myVar, like so:
Code:
DeclareModule myModule
  Define myVar = 123
EndDeclareModule

Module myModule 
EndModule

Debug myModule::myVar   ; == 123

Furthermore, the values for these public variables need not be assigned in the declarations section, and could also be assigned in the module body, like so:
Code:
DeclareModule myModule
  Define myVar
EndDeclareModule

Module myModule 
  myVar = 123
EndModule

Debug myModule::myVar   ; == 123

So, what else could we do with modules?

Procedures are great at modulating reusable functions, saving the need for tediously repetitive code. However, at best, each procedure is capable of performing only a handful of processes. Consider this:
Code:
Procedure myProcedure(a, b)   
  c = a + b
  ProcedureReturn c
EndProcedure

Debug myProcedure(1, 2)   ; == 3

The module-equivalent of the above procedure would look like this:
Code:
DeclareModule myModule
  Declare myProcedure(a, b)
EndDeclareModule

Module myModule 
  Procedure myProcedure(a, b)   
    c = a + b
    ProcedureReturn c
  EndProcedure
EndModule

Debug myModule::myProcedure(1, 2)   ; == 3

Notice how the same procedure has been added into the module, and notice how it has also been declared in the upper declaration section. It is then called in the same method, by prefixing the module name to the procedure name.

At its very core, that's all there is to modules. A glorified procedure with its own namespace. Although that's where the similarities between procedures and modules end.


2. INNER FUNCTIONS
As mentioned earlier, modules are like mini-programs. In addition to their exposed variables and functions, they could also house private ones that are never accessed or referenced by the parent program. For example:
Code:
DeclareModule myModule
  Define myVariable
  Declare myProcedure(a, b)
EndDeclareModule

Module myModule 
  myVariable = 123
  myPrivateVariable = 789

  Procedure myPrivateProcedure()   
    Shared myPrivateVariable
    Debug Str(myPrivateVariable)
  EndProcedure

  Procedure myProcedure(a, b)   
    myPrivateProcedure()
    c = a + b
    ProcedureReturn c
  EndProcedure
EndModule

The variable myPrivateVariable and the function myPrivateFunction() are both inaccessible to the parent program, but they are still able to work within the module itself, called and operated upon by its own functions. A slightly oversimplified example, but it's pretty straightforward.


3. NAMESPACES
To delve further, let's explore the concept of namespaces. We've seen that modules have a unique prefixing syntax with which to reference its elements.
Code:
myModule::moduleVariable
myModule::moduleFunction()

However, there's another way to reference them, provided there are no naming conflicts with the parent program. There is a special closure function that can be used to omit the module prefix when used in the parent program. It's called UseModule/UnuseModule, and the implantation syntax is as follows:
Code:
DeclareModule myModule
  Define myVariable
  Declare myProcedure(a, b)
EndDeclareModule

Module myModule 
  myVariable = 123

  Procedure myProcedure(a, b)   
    c = a + b
    ProcedureReturn c
  EndProcedure
EndModule

UseModule myModule
  Debug myVariable
  Debug myProcedure(1, 2)
UnuseModule myModule

That's really convenient, with one caveat; this convention would fail if the parent program utilises even one identical identifier for any of its variables or functions. In such a case, the UseModule/UnuseModule syntax would not be permitted, so use the module prefix instead.
Code:
myVariable = 456

DeclareModule myModule
  Define myVariable
EndDeclareModule

Module myModule 
  myVariable = 123
EndModule

;UseModule myModule          ; this entire block would
;  Debug myVariable          ; throw a namespace error
;UnuseModule myModule

Debug myVariable             ; == 456
Debug myModule::myVariable   ; == 123


4. INTEROPERABILITY
Now that we've seen how the module makes its variables and functions available to the parent program, how do we get elements from the parent program into the module?
Code:
Global myVersionNumber = 1.23

DeclareModule myModule
  Declare displayVersionNumber()
EndDeclareModule

Module myModule 
  Procedure displayVersionNumber()   
    Debug myVersionNumber
  EndProcedure
EndModule

myModule::displayVersionNumber()   ; == 0 ?

The simple answer is, this is not possible. Not directly, anyway.

To do this, a bridging interface would be required. And for that, we would simply use another module. The manual refers to this as a common module, but it's really just a dummy module whose sole purpose is to relay data between the parent program and the modules in use. It's pretty simple actually.
Code:
DeclareModule globalVars
  myVersionNumber.f = 1.23 
EndDeclareModule

Module globalVars
  ;dummy module used purely as a container
  ;to relay data between parent & modules
EndModule

DeclareModule myModule
  Declare displayVersionNumber()
EndDeclareModule

Module myModule 
  Procedure displayVersionNumber()   
    Debug StrF(globalVars::myVersionNumber, 2)
  EndProcedure
EndModule

myModule::displayVersionNumber()


And that's it! That about covers the basic aspects of modules in PureBasic. I hope that it has been clear and understandable, and at the very least, clarifying some of the common confusions.

Your feedback and comments are always welcome. :D

_________________
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Thu May 10, 2018 8:07 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 6:14 pm
Posts: 1704
Location: Germany (Saxony, Deutscheinsiedel)
Thank you! I like this very much :D

(something which would be good to be integrated into the 'beginners chapter' in the PB manual, but of course only if you agree... ;-))

_________________
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Thu May 10, 2018 8:16 pm 
Offline
PureBasic Expert
PureBasic Expert
User avatar

Joined: Fri Apr 25, 2003 4:34 pm
Posts: 921
Location: Canada
Very nicely done !

_________________
Image Image


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Thu May 10, 2018 10:46 pm 
Offline
Addict
Addict

Joined: Mon Feb 16, 2015 2:49 pm
Posts: 1904
Great tutorial! This thread needs to be made Sticky.


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 4:39 am 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 2213
Location: Singapore
Thank you very much, guys! Always glad to hear it's helpful. :D

Andre wrote:
...good to be integrated into the 'beginners chapter' in the PB manual...
Hi Andre. I'm so honoured that you'd think so. It's all for the PureBasic community, so please use it in any way you'd see fit.

Thanks again. :D

_________________
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 5:33 am 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1710
Location: Uttoxeter, UK
Very instructive. Thank you. :D
Andre wrote:
(something which would be good to be integrated into the 'beginners chapter' in the PB manual, but of course only if you agree... ;-))

+1

_________________
DE AA EB


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 6:52 am 
Offline
Addict
Addict

Joined: Sat Mar 02, 2013 9:17 am
Posts: 931
Hi TI-994A

Still missing is the range definition and handling of global variables in a module and a reference to EnableExplicit, I think...

Regards Werner

_________________
http://www.nachtoptik.de


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 9:31 am 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 2213
Location: Singapore
walbus wrote:
Still missing is the range definition and handling of global variables in a module and a reference to EnableExplicit...

Globals are touched on in the INTEROPERABILITY section, but beyond that, they work pretty much the same way regardless of scope. And EnableExplicit is a compiler directive, but it too works the same way, according to scope.

What range definition are you referring to?

_________________
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 12:48 pm 
Offline
Addict
Addict

Joined: Sat Mar 02, 2013 9:17 am
Posts: 931
Hi
Yes, I know it myself
By the section I meant to explain that global variables declared in a module are available to all procedures in the module, but not outside the module.

Modules should be ever created with EnableExplicit, that's what I meant here
An EnableExplicit in a module is only valid for the module, not outside the module

_________________
http://www.nachtoptik.de


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 1:01 pm 
Offline
Administrator
Administrator

Joined: Fri May 17, 2002 4:39 pm
Posts: 13657
Location: France
Very nice tutorial :)


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Fri May 11, 2018 3:34 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 2213
Location: Singapore
Fred wrote:
Very nice tutorial :)

Thank you, Fred; truly appreciate that. :D

_________________
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Mon May 14, 2018 11:32 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 6:14 pm
Posts: 1704
Location: Germany (Saxony, Deutscheinsiedel)
@TI-994A: As you agreed (thank you! :d) I will try to add the tutorial to the PB manual (beginner chapter) for the next PB version. Thank you! :D

If you plan any changes/additions just give us a note, and please include them in the first post...

_________________
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Tue May 15, 2018 3:27 am 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 2213
Location: Singapore
Andre wrote:
@TI-994A: As you agreed (thank you! :d) I will try to add the tutorial to the PB manual (beginner chapter) for the next PB version. Thank you! :D

If you plan any changes/additions just give us a note, and please include them in the first post...

Thank you, Andre. I'm truly glad. :D

I'll go over it and do the needful.

_________________
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Thu May 17, 2018 8:29 am 
Offline
Moderator
Moderator
User avatar

Joined: Thu Dec 31, 2009 11:05 pm
Posts: 1108
Location: Berlin (Germany)
Nice tutorial.

_________________
ImageImageImageImage Image


Top
 Profile  
Reply with quote  
 Post subject: Re: PureBasic Modules: A Quick Tutorial
PostPosted: Sat Jun 02, 2018 9:41 am 
Offline
Addict
Addict

Joined: Sun Jun 25, 2006 7:28 pm
Posts: 1383
Thank you TI-994A for this lesson about Modules.
apparently you have the spirit of a teacher . so i am sure the users eager for more lessons about tricky things such as pointers and so on over the years.
i suggest to change the title of this tutorial to "Lessons in PureBasic" and then add this as lesson 1. so in the future and over the years you can add lesson 2 and so on in the same thread, while updating the contents in the first page, just a suggestion.
the lessons, tutorials, Documentations are usually very hard to write and needs tremendous efforts.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye