Variable Namespaces
The MJVariableNamespace class stores and organizes variables by variable name or number and scope. Although MJ variables may be used independently of namespaces, namespaces are recommended since they:
- group variables by scope (for example,
LOCAL
vs.GLOBAL
) - correlate named and numbered variables
- allow enumeration of defined variables
- support indirect variables by looking up variables by name or number
An MJVariableNamespace is a registry of named and numbered variables with the same variable scope. To group variables by scope, after declaring a variable, add the variable to the namespace having the same scope as the variable:
// LDV <*global>i6=1001 .
MJVariableNamespace globalNS = new MJVariableNamespace(VariableScope.GLOBAL);
MJNamedInteger globalVar = new MJNamedInteger("_global", globalNS.scope(), 6, Long.valueOf(1001));
globalNS.addVariable(globalVar);
assert globalNS.lookupVariable("_global") == globalVar;
// LDV <$environment>i6=2002 .
MJVariableNamespace envNS = new MJVariableNamespace(VariableScope.ENVIRONMENT);
MJNamedInteger envVar = new MJNamedInteger("$environment", envNS.scope(), 6, Long.valueOf(2002));
envNS.addVariable(envVar);
assert envNS.lookupVariable("$environment") == envVar;
// LDV <counter>i6=0 .
MJVariableNamespace localNS = new MJVariableNamespace(VariableScope.LOCAL);
MJNamedInteger counter = new MJNamedInteger("counter", localNS.scope(), 6, Long.valueOf(0));
localNS.addVariable(counter);
assert localNS.lookupVariable("counter") == counter;
// LDV v23i6=1 .
MJNumberedInteger v23 = new MJNumberedInteger(23, localNS.scope(), 6, Long.valueOf(1));
localNS.addVariable(v23);
assert localNS.lookupVariable(23) == v23;
In the examples above, only named MJ variables are declared with
VariableScope.GLOBAL
or
VariableScope.ENVIRONMENT
. This is the
same as MAPPER, where only named variables can be designated as global or environmental variables.
Retrieving an Aliased Variable
Once added to a namespace, aliased variables can be retrieved from the namespace by either name or number:
// @LDV v45i9='1234567.' .
// @USE intVar=v45 .
MJAliasedInteger intVar45 = new MJAliasedInteger(45, "intVar", VariableScope.LOCAL, 9,
EnumSet.noneOf(LoadOption.class), "1234567.");
assert intVar45.getVariableName().equals("intVar");
assert intVar45.getVariableNumber() == 45;
MJVariableNamespace localNS = new MJVariableNamespace(VariableScope.LOCAL);
localNS.addVariable(intVar45);
assert localNS.lookupVariable("intVar") == intVar45;
assert localNS.lookupVariable(45) == intVar45;
Enumerating Variables
The variables in a given namespace may be enumerated. The example below assumes a namespace with
VariableScope.LOCAL
, where a variable
has both a NAME and a NUMBER if aliased:
Iterator> nsIter = localNS.iterator();
while (nsIter.hasNext()) {
Map.Entry entry = nsIter.next();
if (entry.getKey().keyType == TypeOfKey.NAME) {
System.out.println("named variable " + ((String) entry.getKey().keyValue) +
" = " + entry.getValue().formatter().toFormatted());
}
if (entry.getKey().keyType == TypeOfKey.NUMBER) {
System.out.println("numbered variable " + ((Integer) entry.getKey().keyValue) +
" = " + entry.getValue().formatter().toFormatted());
}
}
Indirect Variables
In MAPPER, the <<name>>
and VVn
syntax
are employed to signify the contents of one variable act as the name (or number) of another variable. MJ refers
to these as indirect variables and supports such variables with namespaces:
// Variable that is target of indirect reference must exist in namespace.
MJVariableNamespace localNS = new MJVariableNamespace(VariableScope.LOCAL);
MJNamedInteger two = new MJNamedInteger("two", localNS.scope(), 2);
assert two.equals(Integer.valueOf(0));
localNS.addVariable(two);
// @LDV <one>h3=two . load <one> with the characters "two"
MJNamedString one = new MJNamedString("one", localNS.scope(),
MaprptVariableType.HOLLERITH, 3, EnumSet.noneOf(LoadOption.class), "two");
localNS.addVariable(one);
// @LDV <<one>>i2=2 . load variable <two> with 2
localNS.lookupInteger(one.toString()).setInteger(2);
assert localNS.lookupInteger("two").equals(Integer.valueOf(2));