Don Schwarz - 2003-09-07

Perl represents strings, integers, floats, and references with a single data type (scalars).  When a scalar is returned from Perl, there are many different ways that we could represent it.

It is easy to tell whether an object is a reference or not, with the ref() operator.  Blessed references (objects) are not currently passed into Java (except by name).  Unblessed references to lists or hashtables are turned into List's or Map's, respectively.  Unblessed references to anything else are wrapped in a PerlReference Java object.

I could have also created a PerlScalar Java class with methods on it to convert to a string, integer, or double.  However, this seemed inconvenient.  I could also have matched the string representation of the scalar to see whether it would be a valid integer or double and converted appropriately.

Instead what I decided to do something logically like the following:

if (($scalar ^ $scalar) eq '0') {
    # XOR thinks it's a number, check what kind
    if ($scalar == int($scalar)) {
        # create a Long
    } else {
        # create a Double
    }
} else {
    # create a String
}

The ^ (XOR) operator checks a flag behind the scenes to determine whether the scalar has been used as an integer.  This will be true if it was returned from, or ever used as an operand in, a numerical calculation.  It also is able to distinguish between numerical constants specified with and without quotes (e.g., 3.14 vs. "3.14").  This seems to work pretty well, though it obviously has limitations.