A variable can be given a token or an expression as its value. To create a variable with a token, either call the appropriate constructor, or create the variable with the appropriate container and name, and then call setToken(). To set the value from an expression, call setExpression(). The expression is not actually evaluated until you call getToken(), getType(). By default, it is also evaluated when you call validate(), unless you have called setLazyValidation(true), in which case it will only be evaluated if there are other variables that depend on it and those have not had setLazyValidation(true) called.
Consider for example the sequence:
Variable v3 = new Variable(container,"v3"); Variable v2 = new Variable(container,"v2"); Variable v1 = new Variable(container,"v1"); v3.setExpression("v1 + v2"); v2.setExpression("1.0"); v1.setExpression("2.0"); v3.getToken();Notice that the expression for
v3
cannot be evaluated when it is set because v2
and v1
do not yet have values. But there is no problem because the expression is not evaluated until getToken() is called. Equivalently, we could have called, for example, v3.validate();This will force
v3
to be evaluated, and also v1
and v2
to be evaluated. There is a potentially confusing subtlety. In the above code, before the last line is executed, the expression for v3
has not been evaluated, so the dependence that v3
has on v1
and v2
has not been recorded. Thus, if we call
v1.validate();before
v3
has ever been evaluated, then it will not trigger an evaluation of v3
. Because of this, we recommend that user code call validate() immediately after calling setExpression(). If the expression string is null or empty, or if no value has been specified, then getToken() will return null.
The expression can reference variables that are in scope before the expression is evaluated (i.e., before getToken() or validate() is called). Otherwise, getToken() will throw an exception. All variables contained by the same container, and those contained by the container's container, are in the scope of this variable. Thus, in the above, all three variables are in each other's scope because they belong to the same container. If there are variables in the scope with the same name, then those lower in the hierarchy shadow those that are higher. An instance of ScopeExtendingAttribute can also be used to aggregate a set of variables and add them to the scope.
If a variable is referred to by expressions of other variables, then the name of the variable must be a valid identifier as defined by the Ptolemy II expression language syntax. A valid identifier starts with a letter or underscore, and contains letters, underscores, numerals, dollar signs ($), at signs (@), or pound signs (#).
A variable is a Typeable object. Constraints on its type can be specified relative to other Typeable objects (as inequalities on the types), or relative to specific types. The former are called dynamic type constraints, and the latter are called static type constraints. Static type constraints are specified by the methods:
The dynamic type constraints are not enforced in this class, but merely reported by the typeConstraintList() method. They must be enforced at a higher level (by a type system) since they involve a network of variables and other typeable objects. In fact, if the variable does not yet have a value, then a type system may use these constraints to infer what the type of the variable needs to be, and then call setTypeEquals().
The token returned by getToken() is always an instance of the class given by the getType() method. This is not necessarily the same as the class of the token that was inserted via setToken(). It might be a distinct type if the token given by setToken() can be converted losslessly into one of the type given by setTypeEquals().
A variable by default has no MoML description (MoML is an XML modeling markup language). Thus, a variable contained by a named object is not persistent, in that if the object is exported to a MoML file, the variable will not be represented. If you prefer that the variable be represented, then you should use the derived class Parameter instead.
A variable is also normally not settable by casual users from the user interface. This is because, by default, getVisibility() returns EXPERT. The derived class Parameter is fully visible by default.
In addition, this class provides as a convenience a "string mode." If the variable is in string mode, then when setting the value of this variable, the string that you pass to setExpression(String) is taken to be literally the value of the instance of StringToken that represents the value of this parameter. It is not necessary to enclose it in quotation marks (and indeed, if you do, the quotation marks will become part of the value of the string). In addition, the type of this parameter will be set to string. In addition, getToken() will never return null; if the value of the string has never been set, then an instance of StringToken is returned that has an empty string as its value. A parameter is in string mode if either setStringMode(true) has been called or it contains an attribute named "_stringMode".
In string mode, the value passed to setExpression(String) may contain references to other variables in scope using the syntax $id, ${id} or $(id). The first case only works if the id consists only of alphanumeric characters and/or underscore, and if the character immediately following the id is not one of these. To get a simple dollar sign, use $$. In string mode, to set the value to be the empty string, create a Parameter in the container that has the value ""
and then set the string mode parameter to the $nameOfTheParameter
. For example, the parameter might be named myEmptyParameter
and have a value ""
; the value for the string mode parameter would be $myEmptyParameter
.
@author Neil Smyth, Xiaojun Liu, Edward A. Lee, Yuhong Xiong
@version $Id: Variable.java,v 1.228 2007/12/07 06:31:23 cxh Exp $
@since Ptolemy II 0.2
@Pt.ProposedRating Red (neuendor)
@Pt.AcceptedRating Red (cxh)
@see ptolemy.data.Token
@see ptolemy.data.expr.PtParser
@see ptolemy.data.expr.Parameter
@see ScopeExtendingAttribute
@see #setPersistent(boolean)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|