Search code examples
cachingenumsintersystems-cacheintersystems

What's the best practice to work with ENUM in Intersystems Caché?


Natively, Caché doesn't implement ENUMs such as Java for example, when you need to implement a solution like the following example in Java, but in Caché, what are the best practices?

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    } 
    private double mass() { return mass; }
    private double radius() { return radius; }
}

final Planet mars = Planet.MARS;

Access to the code as simply Planet.MARS


Solution

  • Example on calculable parameters

    Class so.Enum Extends %RegisteredObject
    {
    
    Parameter MERCURY As COSEXPRESSION = "..%New(3.303e+23, 2.4397e6)";
    
    Parameter VENUS As COSEXPRESSION = "..%New(4.869e+24, 6.0518e6)";
    
    Parameter EARTH As COSEXPRESSION = "..%New(5.976e+24, 6.37814e6)";
    
    Parameter MARS As COSEXPRESSION = "..%New(6.421e+23, 3.3972e6)";
    
    Parameter JUPITER As COSEXPRESSION = "..%New(1.9e+27,   7.1492e7)";
    
    Parameter SATURN As COSEXPRESSION = "..%New(5.688e+26, 6.0268e7)";
    
    Parameter URANUS As COSEXPRESSION = "..%New(8.686e+25, 2.5559e7)";
    
    Parameter NEPTUNE As COSEXPRESSION = "..%New(1.024e+26, 2.4746e7)";
    
    Property Mass As %Double;
    
    Property Radius As %Double;
    
    Method %OnNew(mass, radius) As %Status
    {
        set ..Mass=mass
        set ..Radius=radius
        quit $$$OK
    }
    
    }
    

    and, you can use it so

    USER>w ##class(so.Enum).#MERCURY.Mass
    330300000000000000000000
    USER>w ##class(so.Enum).#MERCURY.Radius
    2439700
    USER>w ##class(so.Enum).#MERCURY.Radius
    2439700
    USER>w ##class(so.Enum).#EARTH.Radius
    6378140
    USER>w ##class(so.Enum).#EARTH
    [email protected]
    USER>w ##class(so.Enum).#MERCURY
    [email protected]
    

    and you can define it as a macros

    #define MERCURY ##class(so.Enum).#MERCURY
    

    or

    #define Planet(%planet) $parameter("so.Enum",$zcvt("%planet","U"))