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:

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));