Working With MJ Variables

String-based initialization with LoadOption

An MJ variable can be initialized via the constructor, which is overloaded to provide multiple ways to instaniate the variable. The constructor combining a string-based, initial value and an enumeration of LoadOption is of particular interest, since it best mimics how MAPPER initializes the variable. The LoadOption enumeration supports:

PACK Remove leading and trailing whitespace from initial value; the length of the trimmed value becomes the packed length of the variable. If the trimmed value is larger than the size of the variable, the trimmed value is truncated to fit.
TRIM Remove leading and trailing whitespace from initial value. If the trimmed value is larger than the size of the variable, the trimmed value is truncated to fit.
TRUNCATE Remove leading and trailing whitespace from initial value. If the trimmed value is larger than the size of the variable, the trimmed value is truncated to fit.
UPPERCASE Characters in the initial value are converted to uppercase (up to the size of the variable) before being stored as the variable value.
LOWERCASE Characters in the initial value are converted to lowercase (up to the size of the variable) before being stored as the variable value.

For example, the initial value of the variable below is converted to lowercase and truncated since it exceeds the size of the variable:

// @LDV,o <myStr>s10='ABCDEFGHIJKL' .
MJString myStr = new MJString(VariableScope.LOCAL, MaprptVariableType.STRING, 10,
  EnumSet.of(LoadOption.LOWERCASE, LoadOption.TRUNCATE), "ABCDEFGHIJKL");
assert "abcdefghij".equals(myStr.toString());

Packing a Variable

As mentioned above, LoadOption.PACK set the packed length of the variable. Once a variable is packed to contain fewer than its original number of characters, the variable must be re-initialized to make it larger. Just like MAPPER, attempting to place more than the original number of characters in a variable results in loss of the extra characters. The following example packs the initial value of a variable, converting it to uppercase, and then sets the value to another string that is larger than the packed size:

// @LDV,pu <pakStr>s10='  abcdef  ' .
MJString pakStr = new MJString(VariableScope.LOCAL, MaprptVariableType.STRING, 10,
  EnumSet.of(LoadOption.PACK, LoadOption.UPPERCASE), "  abcdef  ");
assert "ABCDEF".equals(pakStr.toString());

// @LDV <pakStr>='helloworld' .
pakStr.setString("helloworld");
assert "hellow".equals(pakStr.toString());

Trimming a Variable

LoadOption.TRIM is similar to LoadOption.PACK but does not set the variable's packed length. As such, LoadOption.TRIM does not have an exact corollary in MAPPER. In the example below, the initial value of a variable is trimmed and converted to uppercase. The value of the variable is then set without losing any characters:

// @LDV,u[p] <hstr>h10='  abcdefghijkl  ' . TRIM is similar to [implied] 'p' option
MJString hstr = new MJString(VariableScope.LOCAL, MaprptVariableType.HOLLERITH, 10,
  EnumSet.of(LoadOption.UPPERCASE, LoadOption.TRIM), "  abcdefghijkl  ");
assert "ABCDEFGHij".equals(hstr.toString());

// @LDV <hstr>='helloworld' .
hstr.setString("helloworld");
assert "helloworld".equals(hstr.toString());

Using Scientific Notation

A value for a numeric variable can be provided using scientific notation:

// @LDV <fnum>f10=12.34e+02 .
MJDecimal fnum = new MJDecimal(VariableScope.LOCAL, 10, 0,
  EnumSet.of(LoadOption.TRUNCATE), "12.34e+02");
assert "1234".equals(fnum.toMapperNumericString());

Initialization using a Java type

MJ variables always store values as the underlying Java type. For example, MJInteger always stores its value as a java.lang.Long, while MJDecimal saves its value as a java.math.BigDecimal. An alternative constructor is available that initializes a variable directly from a Java type. Unlike the constructor described above (string-based initialization with LoadOption), this alternative, "Java-centric" constructor does not follow behavior similar to MAPPER's @LDV statement. For example:

MJString mjstr = new MJString(VariableScope.LOCAL, MaprptVariableType.STRING, 10,
  EnumSet.noneOf(LoadOption.class), "  abcdefghijkl  ");
assert "  abcdefgh".equals(mjstr.toString());

MJInteger mjint = new MJInteger(VariableScope.LOCAL, 3, Long.valueOf(1434));
assert Long.valueOf(1434).equals(mjint.longValue());

MJDecimal mjdec = new MJDecimal(VariableScope.LOCAL, 4, 2, BigDecimal.valueOf(1234, 1));
assert 1234 == mjdec.decimalValue().unscaledValue().longValue();
assert 1 == mjdec.decimalValue().scale();

Setting the Value of a Variable

Setter methods parallel the constructors detailed above. Methods exist to set a variable's value from a string-based value combined with LoadOption and to set the value from a Java type. An example of each is shown below:

// @LDV,o <myStr>='ABCDEFGHIJKL' .
MJString myStr = new MJString(VariableScope.LOCAL, MaprptVariableType.STRING, 10);
assert "".equals(myStr.toString());

myStr.setString(EnumSet.of(LoadOption.LOWERCASE, LoadOption.TRUNCATE), "ABCDEFGHIJKL");
assert "abcdefghij".equals(myStr.toString());

// Default initial value is zero.
MJInteger mjint = new MJInteger(VariableScope.LOCAL, 3);
assert Long.valueOf(0).equals(mjint.longValue());

// Set value directly from Java type.
mjint.setInteger(Long.valueOf(1434));
assert Long.valueOf(1434).equals(mjint.longValue());

Nullifying a Variable

It is possible to "nullify" an MJ variable by setting the value of the underlying Java type stored by a variable to null. MJ treats this as analagous to MAPPER's @CLV command. There is a difference in that @CLV deletes the variable from memory, while MJ "deletes" only the value of the variable. The example below nullifies the value of an MJString instance:

// @LDV,C s15='hello, world!' .
MJString myStr = new MJString(VariableScope.LOCAL, MaprptVariableType.STRING, 15,
  EnumSet.noneOf(LoadOption.class), "hello, world!");
myStr.formatter().center();
assert "hello, world!".equals(myStr.toString());
assert " hello, world! ".equals(myStr.formatter().toFormatted());

// @CLV
myStr.setString((String) null);
assert "".equals(myStr.toString());
assert "               ".equals(myStr.formatter().toFormatted());

Getting the Value of a Variable

MJ variable classes provide getter methods to obtain the value of a variable's underlying Java type. Getter methods return a value that is distinct from the formatted value of a variable.

Getting the Value of INumericVariable

Variable classes that implement INumericVariable support methods similar to those present in java.lang.Number:

public Byte byteValue();
public Double doubleValue();
public Float floatValue();
public Integer intValue();
public Long longValue();
public Short shortValue();
public BigDecimal decimalValue();

The numbers returned by the methods above may be different from the "MAPPER" number (the number represented when MAPPER displays the variable, also known as the display value). Use toMapperNumber() to obtain the MAPPER number. Note that toMapperNumber returns null if the underlying value is too large to be properly displayed. For example:

// @LDV <myInt>i3=1434 .          displays ***
// @CHG <mySum>i9 <myInt> + 1 .   displays 1435, MAPPER stored <myInt> as 1434
MJInteger myInt = new MJInteger(VariableScope.LOCAL, 3, EnumSet.noneOf(LoadOption.class), "1434");
assert myInt.longValue().equals(Long.valueOf(1434));
assert myInt.toMapperNumber() == null;

Getting the Value of MJString

The underlying java.lang.String stored by an MJString is returned by toString(). The length() and subSequence() methods also operate on the underlying, raw string.