Frag Logo
  Frag Home | Frag SF Project   index | contents | previous | next

Variables

Object Variables

Variable Slots: Setter, Getter, Unset

Frag uses a slot-based variable system. Each object contains a variable slot table in which variables can be set and unset dynamically, and, of course, variables can be read. For instance, the invocation of the method set:
obj set v 1

creates an integer variable v with the value 1 in the slot table of the object obj. We can read out the variable using the get method:
puts "Value of v: [obj get v]"
We can delete this variable slot using unset:
obj unset v

Defaults

If a class needs to predefine variables to be set for all of its instances, we can use the defaults method, as in the following example:
Object create D -defaults {
    aScalar 1
    aList {}
}

The above defaults statement specifies that whenever an instance of D is created, this instance gets a variable aScalar with the default value 1, as well as an empty list variable aList.

Reflection on Object Variables

At runtime you can find out about variables of an object using the object's predefined instance methods for introspection. For instance, you can query the list of current variables using the following code with getVars:
Object create u
u set u1 1
u set u2 1
u set v 1
puts "The vars are: [u getVars]"
You can also query only for variables that are just starting with a specific pattern:
puts "The vars starting with u are: [u getVars u*]"
It is also possible to check whether a specific variable exists using varExists:
puts "Does a variable x exist? -> [u varExists x]"
puts "Does a variable v exist? -> [u varExists v]"

Local and Global Variables

In Frag, the control flow is always in a specific callframe. Each callframe is placed on the callstack of Frag. On the topmost level of the callstack, you find the global callframe. It is accessed from the toplevel of script files, or when you open the Interactive Shell. In addition, there are method callframes. These are placed on the callstack, when a method is called, and hold the local variables of a method. In both cases, the local variables of the callframe are accessed in the same way.

Just like object variables, the callframe variables can be set, unset, and read. This is done using the Commands set, unset, and get, which work analogously to the object methods:
set x 1
set y 2
set z 3
puts "Value of x: [get x]
In the same way, unset and the introspection options are available, but in the case of callframe variables you have to query the interp object for the variable:
unset x
puts "Does a variable x exist? -> [interp varExists x]"
puts "List of variables in this callframe -> [interp getVars]"
In Frag there is in principle no such thing like global variables. That is, you cannot access the variables that are local to the global callframe from the method callframe. However, for the seldom cases where this is necessary, it is possible to circumvent this restriction using the -global option of the eval Command. In general, however, you should use objects (and their methods) to share state between callframes.

Variable Manipulation Commands

We have already explained the variable concepts of Frag in Section Variable Slots. Frag provides a number of commands for variable manipulation of local and global variables, which we want to explain in this section. Please note that Frag also provides similar methods for object variables. These are explained in Section Object: Method Reference.

get

Syntax

get <var>

Description

get reads a variable var in the current variable scope and returns its value. If the variable does not exist, get throws an error.

Example

A variable is first set and then get and $ are used to retrieve its value.
set i 17
list build [get i] $i

set

Syntax

set <var> <value>

Description

set writes a local variable var and sets its value to the given value argument. set returns the value.

Example

The following code sets a variable using set and then reads it using get:
set r 1
puts "value of r: [get r]"

unset

Syntax

unset <var1> ?... varN?

Description

unset deletes one or more variables from the local scope. It throws an error, if the local variable does not exist.

Example

The following code first creates a variable i, and then unsets it. Hence the catch statement yields an exception with the message can't read variable 'i' when we try to read the variable with get:
set i 17
unset i
set e [catch {get i}]
$e getMsg

subst

Syntax

subst ?-options ...? <string>
Options: -all, -var, -expr, or -code

Description

subst takes a string as input and performs all substitution, which are typically done for code blocks on this string. In contrast to eval, it does not execute the arguments as a command after substitution. You use subst if you have to assemble a text using curly brackets or unparsed regions, and want to perform substitutions in the text. In most cases, you can simply use ordinary substitution with double quotes (...), but this only works, if you do not want to do the substitution in another variable scope (see examples below).

The option -all is the default option, meaning that all kinds of substitutions are performed. Alternatively, only variable substitutions, only expression substitutions, or only code substitutions can be turned on (or any combination of these three kinds of substitutions).

Example

The following code performs a substitution:
set a 111
set text {a text with commands [get a] and variables $a and backslashes \{\} to be substituted} 
subst $text
and returns:
a text with commands 111 and variables 111 and backslashes {} to be substituted
The same could be done by simply using ...:
set a 111
set text "a text with commands [get a] and variables $a and backslashes \{\} to be substituted"
It would not work, if a would be defined in another scope, like a command. Then only subst works:
# use subst in Command scope
set r [Command create -cmd {substText} {
    set a 123
    subst $substText
}]
# assemble code in global scope
set text {a text with commands [get a] and variables $a and backslashes \{\} to be substituted} 
$r $text
The following example demonstrates how the options of subst can be used to trigger only specific kinds of substitutions:
set a 1
set r {$a [get a] (1 + [get a])}
list build [subst $r] [subst -code -expr $r]    
The first list element contains the identical result to what subst $r would provide: 1 1 2, because -all is the default. In the second substitution, -var is not used, but only code and expressions substitution. Hence, $a 1 2 is the result.

  index | contents | previous | next