|
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:
<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:
<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:
<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:
<[
! 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:
<[ 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:
<[
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:
<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:
<[
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:
<[
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:
<[
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( )
]>
|
#####
|