Xbasic Modules

Description

Xbasic Modules can be used to package Xbasic scripts used in a web project. The advantage of Xbasic modules over function libraries is that you can selectively choose what functions are publicly accessible from the module.

Discussion

Xbasic Modules can be managed on the Web Project Control Panel through the Xbasic category.

An Xbasic Module is a text file with a .a5xbm extension. It is stored in the web project folder. The purpose of an Xbasic Module is to allow you to package Xbasic function definitions so that they can easily be used in other Xbasic code you write.

Xbasic Modules

Xbasic Modules are very similar to the concept of Node modules. Xbasic Modules must end with one or more exports commands defining the functions to make publicly available.

Xbasic Modules can contain one or more functions. For example, consider the following Xbasic Module called MyXBModule.a5xbm:

function greeting as c (name as c )
    greeting = "Hello " + ut(name) + " the time is now: " + currentDate()
end function 

function sayGoodbye as c (name as c)
    sayGoodbye = "Goodbye " + name + "."
end function

function currentDate as c ()
    currentDate = date()
end function 

' Export the greeting and sayGoodbye functions:
exports.sayHello = greeting
exports.sayGoodbye = sayGoodbye

The MyXBModule.a5xbm defines three functions, two of which have been exported. Let's take a look at how functions are exported in more depth.

Exposing Functions With "exports" 

The exports object is a dot variable that contains one or more functions to make public. Exported functions can use the same name as the function being exported or be renamed to something else. Only functions that have been exported will be publicly available outside of the Xbasic Module.

In MyXBModule.a5xbm, two functions were exported:

exports.sayHello = greeting
exports.sayGoodbye = sayGoodbye

The greeting() and sayGoodbye() are exported as "sayHello()" and "sayGoodbye()".

The currentDate() function was not exported and therefore cannot be called.

Also notice that the greetings() function was exported as sayHello. This means that to the calling code the function sayHello() can be called (but not the internal greetings() function).

An external Xbasic script or function can call these functions to invoke the greeting() and sayGoodbye() functions in the MyXBModule.a5xbm Xbasic Module by including it using the require() function. For example, the following Xbasic Script includes the module and calls the two functions, displaying the results using the showvar() function:

dim pxb as p
' Include the Xbasic Module
pxb = require("MyXBModule")

dim greeting as c 
greeting = pxb.sayHello("Jim")

dim parting as c
parting = pxb.sayGoodbye("Sue")

' Show variable results:
' (showvar can only be used running in the Developer IDE or desktop application)
showvar(greeting)
showvar(parting)

All functions exported from an Xbasic Module must be listed at the end of the file. You cannot mix exports with other functions. E.g. in the following example, the greeting() function is not exported because it is mixed in with the functions in the Xbasic Module.

Only the functions exported at the end of the Xbasic Module will be publicly available.
function greeting as c (name as c )
    greeting = "Hello " + ut(name) + " the time is now: " + currentDate()
end function 

' Export the greeting function:
' !!!ERROR: sayHello will NOT be created!!!
exports.sayHello = greeting

function sayGoodbye as c (name as c)
    sayGoodbye = "Goodbye " + name + "."
end function

function currentDate as c ()
    currentDate = date()
end function 

' Export the sayGoodbye function:
exports.sayGoodbye = sayGoodbye
sayHello() is not available because it was not exported at the end of the Xbasic Module!

Using the require() Function 

To use an Xbasic Module in your Xbasic code, the module needs to be 'registered' using the require() function. For example, consider the following .A5W page:

<%a5
dim pxb as p
' Include the Xbasic Module
pxb = require("MyXBModule")

' Output sayHello() to Page:
? pxb.sayHello("Jim")

' Output sayGoodbye() to Page:
? pxb.sayGoodbye("Sue")
%>

The Xbasic code in the .A5W page uses the require() function to register the 'MyXBModule' Xbasic Module and assigns the function to a namespace called pxb. To call any of the exported functions, the pxb prefix must be used.

The require() function can take an optional CRLF delimited string of search paths. In a published application, the require() function will look in the webroot for the Xbasic Module. When running in Working Preview or from an Xbasic Script running in the Developer environment, the require() function looks for the module in the Web Project Folder. If the file is not found there, it will search for the module in the "\Xbasic_modules" folder. If you pass in a CRLF delimited string of folder names as the second parameter to the require() function, these folders will also be searched for the module.

For example:

dim pxb as p
dim searchIn as C =<<%str%
\myModules
\thirdPartyModules
%str%

' Include the Xbasic Module
pxb = require("MyXBModule", searchIn)

Including Other Modules in an Xbasic Module 

Modules can also reference other modules. Modules are referenced using the require() function. For example, we could rewrite the MyXBModule.a5xbm to extract the currentDate() function into a new module called DateModule.a5xbm. The MyXBModule.a5xbm could be rewritten as follows:

function greeting as c (name as c )
    ' Include date methods from custom Xbasic DateModule
    ' DateModule.a5xbm contains the implementation for currentDate()
    dim dateModule as p
    dateModule = require("DateModule")

    greeting = "Hello " + ut(name) + " the time is now: " + dateModule.currentDate()
end function 

function sayGoodbye as c (name as c)
    sayGoodbye = "Goodbye " + name + "."
end function

' Export the greeting and sayGoodbye functions:
exports.sayHello = greeting
exports.sayGoodbye = sayGoodbye

What is the Difference between an Xbasic Function Library and an Xbasic Module? 

On the surface an Xbasic Function Library and an Xbasic Module seem similar in that they are both files in which you can define multiple Xbasic functions.

However an Xbasic Module only makes 'public' certain of the functions it defines (through use of the 'exports' keyword) and the exported functions are all in their own namespace and must be called using the namespace prefix.

On the other hand an Xbasic Function Library must be linked into a component before any of the functions defined in the library can be called. The functions defined in the Xbasic Function Library are in the same namespace as any locally defined functions in the component itself.

Exporting Classes 

Xbasic classes cannot be defined in nor exported from an Xbasic Module. Instead, classes can be saved in a separate file with the .a5xbclass extension. See Creating and Loading External Xbasic Class Files for more information.

See Also