faq | docs | tutorials | guide | reference | contact | home  

TUTORIAL - VARIABLES Previous | Next | Tutorial Home

The FGL platform provides a robust environment for the manipulation of data and program variables. FGL is by default an auto-typing environment that initializes variables based on assignment and provides on-the-fly data conversion as necessary. Variable names are not case-sensitive and memory management and resource allocation is transparent and automatic, as is garbage collection and resource optimization and clean-up.

FGL supported data primitives include: string, numeric (integer and float), array, field, null, and object data types. Variants of these core primitives are also provided as subsets of the core FGL primitives.

Variable scoping defines the exposure, visibility, and persistance of an individual data element and includes local, global, static, public, private, protected, inherited, and virtual. Variables can be passed to functions, procedures, and object elements by value or by reference and can include fixed and variable parameters (including full parameter overloading) with optional default parameter values.

It is not necessary to initialize variables within the FGL environment, though good programming constructs dictate the initialization of variables. The FGL run-time engine will generate a warning message for un-initialized variables even though these are non-critical warning messages.

The following example illustrates the use and interaction of standard FGL numeric data types:

Default FGL Variable Types:
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    x = 22                               // creates an integer "x"
    y = 7                                // creates another integer "y"
    z = x / y                            // creates "z" as a floating-point variable
    
    ! "z = " + sprintf( "%-10.2f", z )   // displays the results with two decimal places
]>

</body>
</html>

By default the above example will initialize the “x” and “y” variables as local integers, and the “z” variable as a local floating point variable. The local scoping could have been forced, as in the following example:

Default FGL Variable Types - with initialization:
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    local x, y, z
    
    x = 22                               // creates an integer "x"
    y = 7                                // creates another integer "y"
    z = x / y                            // creates "z" as a floating-point variable
    
    ! "z = " + sprintf( "%-10.6f", z )   // displays the results with six decimal places
    ! "   // to six decimal points"
]>

</body>
</html>

[The sprintf( ) function is fully “C” compatible, though other FGL functions are provided to simplify the manipulation and formatting of data]

Data conversion between different data types is automatic and transparent. Conversion between multiple data terms is determined by the initializing term. For example:

FGL Automated Data Conversion:
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    // initialize some numeric variables
    local x=1, y=2, z=3
    
    // initialize some character sting variables    
    local s1="1", s2="2", s3="3"
    
    ! "<p>Numeric conversion: "
    ! x + y + z + s1 + s2 + s3        // auto-convert to numeric
    
    ! "<p>String conversion: "
    ! s1 + s2 + s3 + x + y + z        // auto-convert to string
    
    ! "<p>Forced auto-conversion: "
    ! "" + ( z * s3 ) + "-" + ( x + y + z ) + "-" + s2
]>

</body>
</html>

In the above example, the last demonstration of variable conversion (“Forced auto-conversion”) uses parentheses to change the order or precedence for the processing of the line. Normally this occurs from left to right (subject to larger order of precedence rules), however, the parentheses force the instructions within the parentheses to be processed first.

In general, the FGL environment will always provide automated conversion to the next most logical and optimized data type, as in integer to long to double to float -- as may be required. This process is completely transparent to the end-user and developer as the FGL platform strives to provide the most efficient and dynamic environment for data manipulation and storage.

FGL strings can either be literal strings, quoted with the single quote character ('), or include embedded control characters using the “C-style” \x control codes, quoted with the double quote character ("). For example:

Literal and control strings example:
<[
    ! webHeader( )
    
    sliteral = 'c:\fgl\server\home'
    scontrol = "c:\fgl\server\home"
    
    ! "<p>Difference between literal and control strings:<br>"
    ! "literal=" + sliteral + "<br>"
    ! "control=" + scontrol + "<br>"
    
    ! "<p>Embedded control codes:<br>"
    scontrol = "this is \ta string with \tcontrol codes\r\n"
    
    ! "<pre>"
    ! scontrol
    ! "</pre>"
    
    ! webFooter( )
]>

Numeric variables support the concept of true and false. Variables equal to zero posses the additional value of false, while variables not equal to zero have the value of true. For example:

True and False example:
<[ session = new( "session" ) ]>
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    
    IsMicrosoft = session.IsMicrosoft( )
    
    ! "<p>"
    if ( IsMicrosoft )
        ! "This browser is Microsoft compatible (TRUE)."
    else
        ! "This browser is not Microsoft compatible (FALSE)."
    end
    
    ! "<p>Inline IF statement:<br>"
    ! "This browser is " + ( IsMicrosoft ? "" : "not" ) + " Microsoft compatible"
]>

</body>
</html>

Un-initialized variables have a default data type of null (undefined). This can be tested for with individual variables as well as function and object method parameters with the FGL type( ) and (JavaScript compatible) typeof( ) functions, as in the following example:

NULL data type example:
<[
    
function DisplayString( str, clr )
    clr = type( clr ) == "C" ? clr : "#FF0000"
    return( "<font color='" + clr + "'>" + str + "</font><br>" )
end
    
]>
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    ! DisplayString( "variable parameter passing and null test example" )
    ! DisplayString( "variable parameter passing and null test example", "blue" )
    
    ! "<p>Type of variable xyz = " + typeof( xyz ) + " (JavaScript compatible)<br>"
    ! "Type of variable xyz = " + type( xyz ) + " (FGL compatible)"
]>

</body>
</html>

The type( ) and typeof( ) functions can be used on any variables type within the FGL environment. Type( ) returns a single character identifying the data type of the variable while the typeof( ) function returns a string compatible with the typeof( ) function in JavaScript.

FGL supports a variety of array structures including single dimensional, multi-dimensional, linear, sparse, ragged, and associative arrays. Array indices are n-based (one by default) and array elements can consist of any valid data type including other arrays, object, or any other FGL data type. For example:

FGL Array example:
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    ! "<p>Single-dimensional array example:<br>"
    a = { "One", "Two", "Three" }
    ! a[1] + ", " + a[2] + ", " + a[3]
    
    ! "<p>Multi-dimensional array example:<br>"
    a = {
        { 1, "One" },
        { 2, "Two" },
        { 3, "Three" },
        { 4, "Four" },
        { 5, "Five" },
        { 6, "Six" }
    }
    cnt = len( a )
    for ( i=1; i<=cnt; i++ )
        ! "" + a[i,1] + ". " + a[i,2] + "<br>"
    end
    
    ! "<p>Associative array example:<br>"
    a = aArray()
    
    a["fish"] = 1
    a["cats"] = 2
    a["dogs"] = 3
    
    ! "Fish=" + a["fish"] + "<br>"
    ! "Cats=" + a["cats"] + "<br>"
    ! "Dogs=" + a["dogs"] + "<br>"
]>

</body>
</html>

FGL object support provides a wide array of variable support, including public, private, virtual, and inherited data types (a detailed discussion regarding objects is provided elsewhere in the tutorial and documentation sections). A simple example includes:

Simple object data example:
<[
    CLASS objMyData
        local fname, lname, city, state, zip, country
    END
    
    obj = new( "objMyData" )
    obj.fname = "Steve"
    obj.lname = "Repetti"
    
    ! webHeader( )
    ! obj.lname + ", " + obj.fname
    ! webFooter( )
]>

The above example demonstrates a class definition for a simple object data container. The following example expands on this basic structure and adds scoping, methods, and virtual variables:

Advanced object data example:
<[
CLASS objMyData
  PRIVATE:
    local userid, password
    
  PUBLIC:
    local fname, lname, city, state, zip, country
    
    METHOD new( userid, password )
        ::userid = userid
        ::password = password
        return( 1 )
    END
    
    METHOD label( )
        local s = ::fullname + "<br>"
    	s += ::city + ", " + ::state + " " + ::zip + "<br>"
    	s += ::country
    	return( s )
    END
    
    ACCESS fullname
        return( ::fname + " " + ::lname )
    END
    
END
    
    session = new( "session" ) 
    obj = new( "objMyData", "smr", "pass" )
]>
<html>
<head>
 <title>FGL Variables</title>
</head>
<body text=black bgcolor=white>

<[
    obj.fname = "Steve"
    obj.lname = "Repetti"
    obj.city = "Plantation"
    obj.state = "FL"
    obj.zip = "33324"
    obj.country = "United States"
    
    ! obj.label( )
]>

</body>
</html>

The FGL platform supports the use of constants as variable types (optimized read-only variables). Constants are defined within the name-space of object classes, though the class does not have to be instantiated in order to use the constants. For example:

Constants data example (with advanced use of objects and codeblocks):
<[
class test
    const  c1 = 5                                 // numeric
    const  c2 = "string"                          // string
    const  c3 = { 5, "string" }                   // array
    const  c4 = {||println ( "hello world" ) }    // codeblock
     
    method out()
        println ( ::c1 )
        (::c4)()
    end
end
    
! webHeader( )
    
x = test::c1                       // direct constant reference
! "a. " + x + "<br>"               // without instantiation of object
    
x = ("te" + "st")::c1              // dynamic name resolution of object
! "b. " + x + "<br>"
    
x = ("test")::c1                   // another dynamic name resolution
! "c. " + x + "<br>"
    
x = test::"c1"                     // dynamic resolution of constant name
! "d. " + x + "<br>"               // within the object
    
x= ("te" + "st")::("c" + "1" )     // dynamic resolution of object and constant
! "e. " + x + "<br>"
    
x = test::c2                       // works with any data type
! "f. " + x + "<br>"
    
x = test::c3                       // including arrays
! "g. " + typeof( x ) + "<br>"
    
// the rest of these examples generate output to the console window
// see the image immediately following this example
    
x = test::c4                       // and codeblocks
    
(test::c4)()                       // variations of codeblock use
    
//test.out()                       // this line would throw an error
                                   // since the object has not been
                                   // instantiated
                                   
test().out()                       // this line works because the first part,
                                   // test() instantiates the object so that
                                   // the call to out() is valid
    
! webFooter( )
]>

#####