Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous
Next: Loops and Conditionals Up: NOTE 195 Getting Started with Glish for AIPS++ Previous: Arrays

Scripts and Functions

Glish code may be written in a file with an editor and executed with the 'include' command. These scripts contain glish code that is identical to the text that you type at the glish prompt. Script files are conventionally given the name extension '.g'. The glish command syntax is

- include 'myscript.g'

The most frequent use of script files is to edit and load function definitions. The syntax may be either

function <fn name> ( <arguments> ) {
    statements
}
or
<fn name> := function ( <arguments> ) {
    statements
}

The 'function' keyword may be abbreviated 'func'. The curly brackets are to group all of the statements together. Without the brackets, only the one statement following the function arguments would be part of the function. Glish is pretty liberal about whether brackets and statements appear on same or different lines and about how you use indentation, as long as the meaning is unambiguous. A function may return any variable type including whole arrays.

Here is a simple function for plotting data from one receiver of one scan in a table.

plot_scan := function (tab, scan_no, receiver=1)
{
    mp := pgplotter()
    data := tab.getcol('DATA');
    scan := tab.getcol('SCAN');
    rcvr := tab.getcol('RECEIVER_ID');

    mask := scan == scan_no & receiver == (rcvr + 1);
    scan_data := data[mask];
    if (length(scan_data) == 0) {
        fail paste('No data found for scan', scan_no, 
                   'receiver', receiver);
    }
    mp.plotxy([1:len(data[mask])], data[mask], 
              title=paste('Scan', scan_no, 'Receiver', receiver));
           return
}

Type this function into a script file, say, 'test.g'. Load it into glish with

- include 'test.g'

and execute the function with

- plot_scan(t1, 48)

There are a few new items in the function definition above. The lines are terminated with semicolons. This is optional both in a script file and at the glish prompt. If you put two lines of code on the same physical line, they must be separated by semicolons. The function contains an if() statement whose argument is normally a boolean expression, but it can be a numeric variable. Zero is false, and everything else is true. 'pgplotter()' and 'mp.plotxy()' are AIPS++ functions. 'paste()' is a glish built-in string concatenation function. 'fail' is a glish built-in that causes an error return; use it like this when you want to signal an error.

Function arguments may be defaulted by assigning them a value in the function definition, as we did with the 'receiver' argument. When a function is called, if no value is given for a defaulted argument, the argument assumes the value given in the function definition. Undefaulted arguments must be given values in a function call. Normally, arguments are given values according to their position in the argument list, but they can be given in any order, if they are named. For example, the plot_scan function call above could also have been done with

- plot_scan(scan_no=48, receiver=1, tab=t1)

The first arguments may be specified by position, but after an argument is named all the rest must be named.

Variables defined by assignment within functions are local to that function. In other words, when the function execution completes the variable goes away. A variable which doesn't disappear may be created by declaring it to be ``global''. Likewise, an externally defined variable may be assigned a value within a function by declaring that variable to be global within the function. For example, look at the results of the execution of two functions defined below.

x := 10
bill := function () {
    x := 5
}
fred := function () {
    global x := 6
}

- x
10
- bill()
F
- x
10
- fred()
F
- x
6

The F that appears after you execute the functions is the glish boolean, False. This is the default return value for functions which do not explicitly return a value. An unusual feature of glish is that global variables can be implicitly referenced from within a function. However, by default, they become local to the function upon assignment, for example,

- gvar := 0.841471
- function x() {
+    print gvar
+    gvar := 90
warning, scope of "gvar" goes from global to local
+    print gvar
+ }
- x()   
0.841471
90
- print gvar
0.841471

Glish provides a warning whenever the scope of a variable goes from global to local. If you want the global variable to be affected, you must explicitly declare it with the 'global' keyword, as in

- gvar := 0.841471
- function x() {
+    global gvar := 90
+ }
- x()
- print gvar
90

Finally, if you don't like the name of a function, or it's too long to type conveniently, you can give it an alias by assigning the function name to another name, just like assigning one variable to another.

- ps := plot_scan	# note no parenthesis
- ps(t1, 48)

Be careful, however! You can wipe out an entire function definition by reassigning it. If you make the assignment,

- plot_scan := 5

the function plot_scan() is gone until you redefine it by including its script file again. However, the variable ps still contains the copy of plot_scan that you assigned to it earlier.

As with variables, you can protect a function name and its arguments with the 'const' keyword, for example,

- const myplot := function (const ary) { ... }

After you have finished debugging a function, it is usually a good idea to protect it with 'const'.


next up previous
Next: Loops and Conditionals Up: NOTE 195 Getting Started with Glish for AIPS++ Previous: Arrays
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15