Defines a user-defined enumeration (also known as an enumerated type or enum). An enum is made up of a list of strongly typed, named constants called members. The value of a variable defined as an enum is restricted to the list of members defined for that enum. Some of the advantages of enums are that they are self-documenting, strongly typed, and validated at compile time (i.e., the compiler verifies that a variable defined as an enum can only contain values defined by that enum).
In addition to being named, each member also has an underlying numeric value associated with it. By default, the compiler sets those associated values automatically. Generally, you do not need to worry about the numerical values, but you can specify one or more of the values explicitly if desired.
You can define two types of enum. In the standard version, a variable defined as an enum can only be assigned one value at a time. You can also define a flag enum. Any variable defined as a flag enum can be assigned any combination of the members (also referred to as "flags" for flag enums) at one time. You can perform operations on flag enum variables to set and unset one or more of the flags.
All enums implicitly inherit from one of two classes. The single-value enums inherit from Progress.Lang.Enum, and flag enums inherit from Progress.Lang.FlagsEnum, which is a subclass of Progress.Lang.Enum. See the Progress.Lang.Enum class and Progress.Lang.FlagsEnum class entries for more information.
| ENUM enum-type-name [FLAGS]:
    DEFINE ENUM enum-member-definition
              [enum-member-definition] ...
END [ENUM].     | 
The following example shows how to define an enum with the four cardinal directions as its named values:
| ENUM Direction:
    DEFINE ENUM North
                South
                East
                West.
END ENUM.			 | 
The next example shows how to define an member as equivalent to another:
| ENUM Direction:
    DEFINE ENUM North
                Default = North
                South
                East
                West.
END ENUM.			 | 
In this case, both North and Default have an underlying value of 1.
The following is an example of a flag enum, including the member ReadWrite being defined as a combination of previously defined members:
| ENUM Permission FLAGS:
    DEFINE ENUM None = 0
                Read
                Write
                Update = Write
                ReadWrite = Read,Write
                Create
                Delete
                Execute.
END ENUM. | 
For flag enums, it is recommended that you include an member with an underlying value of 0, representing no flags set. Because the compiler automatically starts with a value of 1 for both single-value and flag enums, you must define an member with a value of 0 explicitly.
The syntax for assigning a value to a variable defined as an enum is similar to the syntax used to assign values to static data members of a class:
| enum-type-name:member-name | 
Using the Direction enum from the first example, this code fragment defines myDirection as a variable of type Direction and assigns myDirection the member South:
| DEFINE VARIABLE myDirection AS Direction. myDirection = Direction:South. | 
This syntax cannot be used to set multiple flags for a variable defined as a flag enum. To set multiple flags, you need to use bitwise operators or the SetFlag( ), ToggleFlag( ), and UnsetFlag( ) methods, as described in the Notes section of this entry.
Members are read-only, so the following code will not compile:
| Direction:South = myDirection. | 
Like other uninitialized class references, variables defined as enums have an initial value of the unknown (?) value.
| METHOD PUBLIC Permission SomeOperation (INPUT perm AS Permission): END. PROCEDURE proc: DEFINE INPUT-OUTPUT PARAMETER perm AS Permission. END. FUNCTION func1 RETURNS Permission (OUTPUT perm AS Permission): END. | 
| DEFINE VARIABLE myDirection AS Direction.
myDirection = Direction:GetEnum("South").
myDirection = Direction:GetEnum(2).			 | 
| DEFINE VARIABLE myDirection AS CLASS Direction. | 
| ENUM Direction:
    DEFINE ENUM North
                South
                East = 4
                West.
END ENUM.			 | 
In this case, the underlying values for the members are still automatically set by the compiler as 1 for North, 2 for South. East is explicitly set as 4, so the compiler sets the value of West as one larger than the previous member, which in this case will be 5. The same rules hold true for flag enums, except that the compiler assigns the next power of 2 to each member that does not have its underlying value explicitly set.
When you have to explicitly set the underlying value of an member, you can use hexadecimal notation, particularly for ease of readability with flag enums. Following is the Permission enum with the underlying values explicitly set:
| ENUM Permission FLAGS:
    DEFINE ENUM None = 0
                Read = 0x01
                Write = 0x02
                Update = 0x02
                ReadWrite = 0x03
                Create = 0x04
                Delete = 0x08
                Execute = 0x10.
END ENUM. | 
| ENUM Direction:
    DEFINE ENUM North
                South.
    DEFINE ENUM East
                West.
END ENUM.			 | 
The same rules for how the compiler assigns the underlying numerical values still apply, i.e., in the example above, South has an underlying value of 2, and East has an underlying value of 3. In other words, the underlying numerical values will be assigned according to the order of the members, regardless of whether or not the member list is split into multiple DEFINE ENUM statements.
The following comparison operators can be used with enums, as long as the two expressions being compared are both defined as the same enum type:
When used with expressions that are enum types, the operators compare the underlying numerical values of the members. Comparisons can be made using either single-value enums or flag enums. Using the previously defined Direction enum, this code fragment shows a comparison and results in the message being displayed:
| DEFINE VARIABLE myDirection AS Direction.
myDirection = Direction:South.
IF myDirection NE Direction:North THEN
   MESSAGE "The current heading is not north." 
      VIEW-AS ALERT-BOX.			 | 
You can only use the comparison operators for two expressions defined as the same enum type.
The CompareTo( ) method of Progress.Lang.Enum also allows you to compare enum instances based on the members' numeric values. See the CompareTo( ) method entry for details.
| DEFINE VARIABLE myDirection AS Direction.
myDirection = Direction:South.
CASE myDirection:
   WHEN Direction:North THEN
      MESSAGE "Your current direction is north.".
   WHEN Direction:South THEN
      MESSAGE "Your current direction is south.".
   OTHERWISE
      MESSAGE "Your current direction is east, west, or unknown.".
END CASE.
			 | 
| DEFINE VARIABLE myPermission AS Permission.
myPermission = Permission:ReadWrite.
CASE myPermission:
   WHEN Permission:Read THEN
      MESSAGE "You can read data.".
   WHEN Permission:Write THEN
      MESSAGE "You can write data.".
   OTHERWISE
      ...
END CASE.
			 | 
Using the Permission enum from the Examples section, the following examples show use cases of the bitwise operators:
| DEFINE VARIABLE myPermissions AS Permission. /* myPermissions is set with a Permission instance with the Read and Write flags set. */ myPermissions = Permission:Read OR Permission:Write. /* All flags are set with the possible exception of Create, which is toggled. */ myPermissions = myPermissions XOR Permission:Create. /* Ensures that the Create flag is not set. */ myPermissions = myPermissions AND NOT Permission:Create. /* All flags are set except Create. */ myPermissions = NOT Permission:Create. /* Checks to see if Read is set. */ IF (myPermissions AND Permission:Read) = Permission:Read THEN ... /* Three additional ways to check if Read is set. */ IF (myPermissions AND Permission:Read):Equals(Permission:Read) THEN ... IF myPermissions:IsFlagSet(Permission:Read) THEN ... IF (myPermissions AND Permission:Read) NE Permission:None THEN ... | 
| IF enum1 AND enum2 OR iCount <> 1... | 
See the Expression entry for the full table of operator precedence.