Gambas Scripting

Gambas Scripting

Introduction

The Gambas Scripter is a text based front end for the Gambas interpreter. The applications/Scripts are simple text files editable by any Linux editor. These scripts are an excellent way to write scripts where BASH does not provide the complex data types and data handling required by the programmer. Gambas script's mime type are recognized by the OS in the same way BASH or DASH scripts are recognized. Scripter is well integrated into the Linux shell environment with env[<env variable>] giving direct access to the shell environment variables. Scripter does not require the complex interface provided by the full Gambas IDE. In fact, the IDE is not required at all to use Gambas scripts. Scripter is an excellent alternative to BASH for implementing complex system management procedures quickly. Bringing the full breadth of a well implemented programming language to the programmer. This allows scripts to use graphic and text base interfaces. Gambas scripts are optimized as they are compiled, and the compiled script is cached and recompiled only if the script is changed. This vastly improves system performance and response when running Gambas scripts. Scripter can also be used to compile and execute the more traditional Gambas project.
Since 3.16
Scripter may also be used as a component to a Gambas Application allowing the application to dynamically load or create text based scripts which can be directly loaded and executed by the application. The loaded script will have access to the applications classes and public class variables. Note:
 Throughout this document Scripter and gbs3 are used interchangeably.
 The actual Linux executable is gbs3

Scripter - How it works

The Scripter(gbs3) works by: creating a temporary project from your script, compiling it, and running it.
Since 3.16
The Gambas Scripter gbs3 can also directly execute a project without the use of the IDE. The compiled project is cached so that it is executed immediately if you run the project again. The Scripter can also be used to generate a component which can be loaded and used at runtime. Example: directly execute a script file
> gbs3 ~/myscripts/script1.gbs
> ./script1.gbs
Since 3.16
Example: directly execute a project
> gbs3 ~/myprojects/project1

Creating a Script

To create a Gambas script file, make it executable and write this preamble at the beginning:
#!/usr/bin/env gbs3
The Scripter can execute free-form programs with ease. To achieve this, Scripter will collect your free-form commands into a Main() subroutine automatically while maintaining the integrity of subroutines/structures/class separately.
#!/usr/bin/env gbs3
sub PrintBye()
 print "Bye"
end
dim sHello as string = "Hello"
Print sHello
PrintBye()
The Gambas script can also be written like a module in a common Gambas project, the interpreter automatically executes a Main() subroutine when included in the script. TIP: Scripts execute more quickly if your code includes a Sub Main() subroutine rather than using the free-form method of writing a script. This is due to the Scripter not having to collect the free-form code and create a Main() subroutine.
Since 3.17
A script will return the script name from application.name rather than the temporary file name created when compiling the script.
#!/usr/bin/env gbs3
Public Sub Main()
 DoPrintHello()
End
Private Sub DoPrintHello()
 Print "Hello"
End
The code can be organized with private and public subs and functions, and constants and variables just like in Gambas modules inside Gambas projects.

Installing Scripter - gbs3

Scripter is not installed by default when the IDE is installed onto your system. It must explicitly be installed before it is available. It needs to be installed through your distributions package manager.
For example on Mint/Ubuntu the following command could be used
 sudo apt install gambas3-gb-scripter
See your distribution package manager for specifics. To use Scripter it is not required to have the Gambas3 IDE installed.
Scripter can be installed standalone. When installed Scripter will cause the gambas-devel package containing the compiler linker and archiver to be installed and also the gb.pcre component if they are not already present on the system. When installed standalone, the user will be required to individually install any components needed by executed scripts.

Defining Classes and Structures within a Gambas script

Unlike a Gambas project, Scripts support Classes and Structures in a script-specific way. Classes are defined inline within your script code, structures must be public and defined before any reference to them in the script.

Defining a class inline

To define a class the following format is used:
 #!/usr/bin/env gbs3
 Public sMyVar1 as string
 Public oMyClass as new MyClass
 class MyClass
 sub sub1()
 print "hello"
 end
 end class
 oMyClass.sub1()
A Class's data and functions are defined in the same way as in the IDE except you must add the Class and End Class statement. Notice that the class does not have to be defined before it is used.

Defining a structure inline

Structures, which are a special case of class, must be defined before any reference to that structure. All structures must be declared as Public and are Global.

Examples of defining Structures

 #!/usr/bin/env gbs3
 Public sMyVar1 as string
 Public oMystruct as new MyStruct
 Public Struct MyStruct
 sText as string
 end struct
 oMystruct.sText = "hello"
The above example will fail! The correct method is
 #!/usr/bin/env gbs3
 Public sMyVar1 as string
 public struct MyStruct
 sText as string
 end struct
 Public oMystruct as new MyStruct
 oMystruct.sText = "hello"

Executing a Gambas script

There are two ways to execute a Gambas script You may create a non-executable file as in the example below. From a file named MyScript.gbs containing:
Public Sub Main()
 DoPrintHello()
End
Private Sub DoPrintHello()
 Print "Hello"
End
This may be executed with:
gbs3 MyScript.gbs
An alternative to this, and most commonly used, is to provide the command inside the file and make it executable.
From the file myscript.gbs containing the following:
 #!/usr/bin/env gbs3
 Public Sub Main()
 DoPrintHello()
 End
 Private Sub DoPrintHello()
 Print "Hello"
 End
If the file is made executable with
chmod 755 myscript.gbs
Then it can be executed with the simple command:
./myscript.gbs
from the current directory. If we want to make this a command for general personal use it can be copied to:
 ~/bin
or for more general use to:
 /usr/bin

Passing Arguments To The Script

There is an ARGS[] array which contains arguments passed by command line.
#!/usr/bin/env gbs3
Dim arg as String
Dim i as Integer
for each arg in ARGS
 Print "Argument Nr. " & i & " = " & arg
 Inc i
next
See that position 0 of ARGS is used by Gambas itself, it contains the path to the cached compiled project:
$ ./test.gbs ding dong
Argument Nr. 0 = /tmp/gambas.1000/script-cache/b1826db433d3855de7e021ca9ad34b87/test.gbs
New for 3.15.3 Arg 0 now reports the name of the script correctly as test.gbs
Argument Nr. 1 = ding
Argument Nr. 2 = dong
Note: It is possible to get the name of your original script using file.name(args[0])

Using Scripter gbs3 as a component in your project

Since 3.16
It is possible to use Scripter gbs3 as a component in your project. Scripter provides three interfaces: The first is for dynamically loading plugins and is defined as follows:
 '' This allows integration of scripter into an application that uses plugins
 '' the call would be ScripterPlugin(MyScript,"-b -c etc these are other parameters")
 '' This returns the instantiated class of the plugin script
 ScripterPlugin(ScriptPath As String, Optional CompileParameters As String[] = [],
 PluginNewParameters As Variant[] = Null) As Variant
 ScripterPlugin.fromString(ScriptName As String,ScriptText as string,
 Optional CompileParameters As String[] = [],
 PluginNewParameters As Variant[] = Null) As Variant
 ScripterPlugin.SetVerbose() 'Turns on verbose information
The second allows the execution of a script from text and return its output
 ScripterExecute(ScriptName as string,ScriptText As String,
 Optional CompileParameters As String[] = [],
 PluginNewParameters As Variant[]) as variant
and the third is for executing a script directly returning the exit code and is defined as follows:
'' execute a script and return the exit code
'' aArgs[0] being the script name
Scriptmain.ScripterMain(aArgs As String[]) As Integer

When plugin Compile Fails using ScripterPlugin/ScripterExecute

Since 3.16
When a plugin load fails the result returned will be null the return code from the compiler is available from the class static variables :

ScripterPlugin error access:

 Static Public CompileResult As Integer = 0 '' Result return by the gambas compiler
 Static Public CompileErrorText As String = "" '' will contain the list of errors found
 ScripterPlugin.CompileErrorText
 ScripterPlugin.CompileResult

ScripterExecute error access:

 Static Public $sLastError As String = ""
 ScripterExecute.$sLastError

Loading the gbs3 component

Since 3.16
To include gbs3 as a component in your application the following code is required
dim Scripter,ScriptMain,ScriptExecute as object
component.load(system.find("gbs3"))
Scripter = class.load("ScripterPlugin").new()
ScriptExecute = class.load("ScripterExecute").new()
Scriptmain = class.load("ScriptMain").new()
once this is done it is just a matter of calling the interface
dim myplugin1 as object = Scripter("~/myplugins/MyPlugin1")
myPlugin1()
dim myplugin2 as object = Scripter.fromString("MyClass","print \"Hello World\"")
myPlugin2()
or to execute a text script and get the output
dim result as variant
result = ScriptExecute("MyClass2","Print \"hello world\"\nPrint \"This is also returned\"")
or to execute a script by passing the command line parameters returning the exit code for example:
dim result as integer
result = ScriptMain.ScripterMain(["-v","-f","~/myscripts/MyScript1.gbs","Script parm1","Parm2"])

Creating Plugins using Scripter --plugin

Since 3.16
Scripter can create plugins that can be used by other scripts or Gambas applications after being built using the --plugin or -p option. The term plugin is synonymous with the term component throughout this document. Plugins are created in a user-selected directory and are also executed from and cached in this directory, unlike a normal script, in which executables are created in the temp directory and are executed from there. This allows plugins to persist after the Scripter exits. When a plugin script is cached it will not be recompiled Scripter will return with no error. If no output destination is specified, then the plugin is created in the:
 ~/.local/lib/gambas directory.
Plugins may be loaded from there using the component.load() function. Scripts being used as plugins are generated with the entry point defined as
 with a class of the same name as the base name of the script
 _Call(...) as variant
by default. A Scripter generated plugin source may look like this for a plugin script from:
print "hello"
to:
Class MyPlugin1
 public sub _Call(...) as variant
 print "hello"
 end
end class
So inside your script the parameters are accessed using the param gambas class. It is also possible to define the entry point yourself with fixed parameters.
_Call(counter as integer) as integer
from:
public sub _Call(count as integer) as integer
 print count
end
to:
class MyPlugin1
 public sub _Call(count as integer) as integer
 print count
 end
end class

Example: Building an App that uses plugins

Since 3.16
 Define some simple plugins/components for testing
 ~/myscripts/MyPlugin1.gbs:
 print "The Parameter was",param[0]
 return "This was done"
 ~/myscripts/MyPlugin2.gbs:
 print "Number of parameters passed=",param.count
 return "So was this"
 ~/myscripts/MyPlugin3.gbs:
 public sub _Call(counter as integer) as integer
 for i as integer = 0 to counter
 print i;
 next
 return i
 end
 Execute gbs3 to create a component plugin.
 > gbs3 --plugin ~/myscripts/MyPlugin1.gbs ~/myplugins
 > gbs3 --plugin ~/myscripts/MyPlugin2.gbs ~/myplugins
 > gbs3 --plugin ~/myscripts/MyPlugin3.gbs ~/myplugins
 Now in the script that requires the plugin, they can be loaded as in the following script:
 #!/usr/bin/env gbs3
 dim MyPlugin1,MyPlugin2,MyPlugin3 as object
 ' Make sure we have the latest version, assume all compiles are perfect..
 exec ["gbs3","--plugin","~/myscripts/MyPlugin1.gbs","~/myplugins"] 'if already in cache and no change then just returns
 exec ["gbs3","--plugin","~/myscripts/MyPlugin2.gbs","~/myplugins"]
 exec ["gbs3","--plugin","~/myscripts/MyPlugin3.gbs","~/myplugins"]
 ' Load the plugins
 component.load(User.home &/ "/myplugins/MyPlugin1")
 MyPlugin1 = class.load("MyPlugin1").new()
 component.load(User.home &/ "/myplugins/MyPlugin2")
 MyPlugin2 = class.load("MyPlugin2").new()
 component.load(User.home &/ "/myplugins/MyPlugin3")
 MyPlugin3 = class.load("MyPlugin3").new()
 ' Now lets access and call the plugin
 print MyPlugin1("some parameter")
 print MyPlugin2("one","two","three")
 print MyPlugin3(100)
This ability is most useful in an application which creates the script on the fly and then incorporates it into the application with access to all application classes.
 #!/usr/bin/env gbs3
 dim thenewone as object
 file.save("~/myscripts/thenewone","For i as integer = 0 to 100\nprint i;;\nnext\nprint classes.count")
 exec ["gbs3","--plugin","~/myscripts/thenewone","~/myplugins"]
 component.load(User.home &/ "/myplugins/thenewone")
 thenewone = class.load("thenewone").new()
 thenewone()

Example: Combining gbs3 as a component and using script based plugins

Since 3.16
Now in this example if we combine using gbs3 as a component and using plugins we have the following:
#!/usr/bin/env -S gbs3 -a
dim MyPlugin1,MyPlugin2,MyPlugin3,thenewone as object
dim Scripter as object
component.load(system.find("gbs3"))
Scripter = class.load("ScripterPlugin").new()
MyPlugin1 = Scripter("~/myscripts/MyPlugin1.gbs")
MyPlugin2 = Scripter("~/myscripts/MyPlugin2.gbs")
MyPlugin3 = Scripter("~/myscripts/MyPlugin3.gbs")
TheNewOne = Scripter.fromString("TheNewOne","For i as integer = 0 to 100\nprint i;;\nnext\nreturn classes.count")
' Now lets access and call the plugins
print MyPlugin1("some parameter")
print MyPlugin2("one","two","three")
print MyPlugin3(100)
print thenewone()

Filtering Script Text for plugins

Since 3.16
When using loading or generating script based plugins within an application it is possible to filter the text in the script in order to restrict access to classes or functions in that script. This can be accomplished by creating a filter table and passing it to the Scripter class. The filter table is a collection that is defined as follows:
 dim filter as collection = [ "Error message 1":"regular expression to match as error check",
 "Error message 2": "regular expression 2",
 .... etc ]
Each entry in the table defines and error set and the regular expression that would cause that error. So to prevent some action or access in a script it may have defined:
 dim filter as collection = ["Print statement not allowed":"(?:^|\\W)print(?:$|\\W)", ' yes this is a very simple example no printing!
 "Write statement not allowed":"(?:^|\\W)write(?:$|\\W)", ' don't allow a write
 "Access forbidden classes":"^.* classes[ .]"] ' prevent accessing the classes[]
This filter may be activated by calling:
 ScriptSetKeywordFilter(filter)
Scripter will print the error text and line number within the script and then halt the building of the plugin.

Components and Libraries - use

Gambas Components and Libraries can be used with the command USE

Including Other Gambas Script Files - #include

The Include keyword has been replaced with #Include preprocessor keyword
Since 3.16
For backwards compatibility Include will continue to be support until the next release. Programmers should convert all code to use #Include before that release. Other Gambas script files can be included with the command INCLUDE or #INCLUDE

Using the Gambas Jit feature with scripts

It is possible to Compile and execute your scripts more quickly in some cases using the Gambas Just in Time Compiler feature. These featured may be enabled with the: -f fast option - use the jit and -u Unsafe option - remove any validation checks from code. There are Three ways to invoke this with a script the first is from the command line
gbs3 -f -u MyScript
Or as part of the #! in your script:
#!/usr/bin/env -S gbs3 -f -u
Public Sub Main()
 DoPrintHello()
End
Private Sub DoPrintHello()
 Print "Hello"
End
Or simply at the beginning of your script:
#!/usr/bin/env gbs3
Fast Unsafe
Public Sub Main()
 DoPrintHello()
End
Private Sub DoPrintHello()
 Print "Hello"
End

Script Naming Convention

By convention gambas scripts will have the .gbs extension, but this is not a requirement your script may be named anything with almost any extension or no extention at all. The script is actually recognized by the shell at execution time by the:
#!/usr/bin/env gbs3
as the first line of your script.

Using Command Line Scripts with -e option

It is possible to execute a quick Gambas3 script from the command line with the format:
 gbs3 -e "dim i as integer:for i = 0 to 100 : print i: next"
Note that it is possible to have multiple statements separated by the : character.
 gbs3 -e 'dim b as collection = ["a":"b"]:dim i as integer:for i = 0 to 100 : print i: next'
If you need to pass a string from command line then you will need to use ' not " to surround the program. In bash and sh etc. the command line script should be encased in ".." or '..'

Using Short form Variable declaration on command line

NOTE: This feature is no longer supported
Since 3.16

When writing a command line script it is possible to add a short hand for the definition of variables. The above example could be rewritten as:
 gbs3 -e -p "for {i}counter = 0 to 100 : print counter: next"
With the -p or preprocess option when any variable name is preceded by a {} and contains one of the following supported variable types.
"i": "Integer" "s": "String" "f": "Float"
"d": "Date" "b": "Boolean" "v": "Variant"
"o": "Object" "l": "Long" "p": "Pointer"
When this notation is used then gbs3 will generate the correct dim statement for the variable.

#Script keyword

Since 3.16
This keyword is used to add information to your script, which will be used by Scripter to construct the Gambas project from the inline source file. The format of this keyword is
 #Script keyword=value
Currently the following keywords are supported
KeyWord Description Content
TYPE type of project Defaults to " " normal | can be Library, Component
VERSION project version number Defaults to "0.0.1"
DESCRIPTION Description of the project Any text
MAINTAINER person maintaining app name of person
AUTHOR or AUTHORS Who Wrote This Coma separated list
VENDOR Vendor name Defaults to "Ordinary"
LICENSE Type of license Defaults to "General Public License 2.0"
TITLE Text of project title Defaults to "Gambas Script"
NAME Name of script Defaults to Script file basename
STARTUP defines the class/module to start.
Scripter uses this name to identify/create the default class or module.
When the script/Plugin executes this will be the class-_Call()/module-main() that is started.
Defaults to Scripts = "MMAIN",
Plugins = BaseName(file name without extension)
HEADER The first line of the generated project file Defaults to "# Gambas Project File 3.0"

Converting a Script to a project with --convert-script

Since 3.16
Using the --convert-script parameter with gbs3 will allow the user to create a project directory from an existing script. There are some limitations to this conversion. In general most gambas source file type are supported by the script conversion. Form, Connection, WebPage, WebForm file formats are very Gambas specific, so be careful with these file formats The project is created in the specified directory and the directory has the same basename as the script file

Example

gbs3 --convert-script ~/myscripts/project1.gbs ~/myprojects will take the script project1.gbs and create the project directory ~/myprojects/project1

Converting a project to a script with --convert-project

Since 3.16
Using the --convert-project parameter with gbs3 will allow the user to create a script file from an existing project. There are some limitations to this conversion. In general most gambas source file type are supported by the project conversion. Form, Connection, WebPage, WebForm file formats are very Gambas specific, so be careful with these file formats. The output script file is placed in the defined directory and is named the same as the project directory with the .gbs extension

Example

gbs3 --convert-project ~/myprojects/project1 ~/myscripts will take as input the project1 directory and output a script ~/myscripts/project1.gbs

Supported source file types

Since 3.16
In General for use only Classes and main module are defined. in most cases the other supported types are only used by the automated project to script conversions. The following definitions are supported for script files
Class className
....
End Class
Module ModuleName
 ...
end Module
The following Types are experimental:
Form FormName
...
End Form
Connection ConnectionName
...
End Connection
WebForm FormName
...
End WebForm
WebPage PageName
...
End WebPage

Executing web forms and web apps from command line

Since 3.16
Web form and web app scripts me be launched using the following bash command line. These are limited to simple display functions as scripts.
 ./TestWebApp.gbs > ~/webpage1.html && firefox ~/webpage1.html
 ./TestWebForm.gbs > ~/webpage1.html && firefox ~/webpage1.html
To Use a Web App correctly goto Gambas Web App

Getting a list of components installed and available on your system with -l Component

Since 3.15
To get the list displayed on the console then execute Scripter with -l parameter
 gbs3 -l Component

Getting a list of libraries installed and available on your system with -l Library

Since 3.15
To get the list display on the console then execute Scripter with -l Library
 gbs3 -l Library

Scripter command line args

Since 3.16
Usage:
 gbs3 [options][--] [<script file> | <project directory> | - ]
 gbs3 --convert-project <input project directory> <output script directory>
 gbs3 --convert-script <input script> <output project directory>
 gbs3 --plugin <input script> [<output plugin cache directory>]
Options: -b --buildonly process and compile the script without executing it -c --nocache force the script compilation (do not check cache) -e execute the source code provided by the command line ( : separator ) -g --debug add debugging information to application -f --fast use just-in-time compiler -h --help display this help -l --list Display the list of available -l component or -l library -L --license display license -p --plugin Compile the script, no main, define the class name as script base name entry point _Call(...) -S --strict fail if Public or Sub are defined without a main function -t --trace turn on tracing option during execution -T --terse-listing only print a very terse error report on compile errors -u --use force component loading (comp1,comp2...) -U --unsafe allows jit compiler to generate unsafe faster code -v --verbose be verbose -V --version display version -w --warnings display warnings during compilation --convert-project convert a simple project to a script --convert-script convert a simple script to a project -- stop any further option processing - read the script from standard input

-b --buildonly

Since 3.16
Process and compile the script without executing it. This will also generate the cache version if successfully compiled. So when the script is executed it directly executes the Gambas executable previously generated for the script. An application can execute Scripter with this option verify the compile completed without error then execute the script with very little penalty in performance.

-c --nocache

Forces the script compilation (do not check cache)

-e

Execute the source code provided by the command line ( : separator )

-g --debug

Add debugging information to the generated Gambas application executable

-f --fast, -U --unsafe

use just-in-time compiler, -U allows jit compiler to generate unsafe faster code

-S --strict

Since 3.16
Fail if Public or Sub are defined without a main for scripts or _Call for plugins

-T --terse-listing

Since 3.16
Only print a very terse error report on compile error. Normally the Scripter will print a full listing of the offending file and mark the line and location of the error. In this mode it will only display the offending line and mark the error location on the line.

-u --use

Force component loading (comp1,comp2...)

-v --verbose

Be Verbose. When enabled the Scripter prints information about the creation of the project and final Executable file. It will also display a start of execution message with a start time stamp. When the script ends execution it will display an end of execution message with an end time stamp. It will then display the total execution time of the script.

-w --warnings

Display warnings during Script compilation and project build activities.

-l library

Display the list of libraries accessible by your script

-l component

Display the list of components accessible by your script

AltStyle によって変換されたページ (->オリジナル) /