ooRexx logo
   1: #!/usr/bin/env rexx
   2: /** 
   3:  * The prolog code performs some simple tests for the different possibilities
   4:  * to create an Enumeration
   5:  *
   6:  *  a.  Only symbols as key/index, where the ascending integer values/items will
   7:  *      be done by the Enumeration  creation, starting at zero.
   8:  *
   9:  *  b.  Combination of keys with values, where the key/ndex can be an OORexx 
  10:  *      string and the values/items can be any OORexx object, inclusive numbers. 
  11:  *
  12:  *  c.  An array containing 2-item arrays where the 2-item arrays contain
  13:  *      the possible combination of the b. case, i.e array index 1 is a String,
  14:  *      array index 2 can be anything.
  15:  *  
  16:  **/
  17: level = .Enumeration~of(LOW,MEDIUM,HIGH,LEVELS)
  18: say '----  Automatic sequencing from 0 -----'
  19: say low '=' level[low]
  20: say 'There are' level['LEVELS'] 'levels'
  21: say medium '=' level[medium]
  22: say '----- Bitlevels -----'
  23: options = .Enumeration~of((BOLD,1),(ITALIC,2),(UNDERSCORE,4))
  24: say bold'+'italic '=' options[bold]+options[italic]
  25: say '----- Strings -----'
  26: colours = .Enumeration~of((RED,'800000'),(GREEN, '008000'),(BLUE,'000080'))
  27: say blue '=' colours[blue]
  28: say red '=' colours~red
  29: say '----- Objects -----'
  30: objects = .Enumeration~of((OBJ1, .object~new), (OBJ2, .array~new), ('obj3', .table~new))
  31: --say 'enum type =' objects~type
  32: say obj2 'is a' objects['oBj2']~class~id 'instance'
  33: say obj3 'is an instance of' objects~obj3 'class'
  34: say '----- 2-item Array -----'
  35: fonts = .array~of((ULTRALIGHT,100),(LIGHT,200),(MEDIUM, 500),(HEAVY,800), (ULTRAHEAVY,1000))
  36: font = .Enumeration~of(fonts)
  37: say 'The font''s MEDIUM weight is:' font~medium 
  38: 
  39: exit
  40: 
  41: ::OPTIONS NOPROLOG
  42: 
  43: /**
  44:  *  Class: Enumeration
  45:  *
  46:  *  An OORexx implementation of the well known ENUM's in other languages like C(++),C#,
  47:  *  Java etc..
  48:  *
  49:  *  ENUMs are normally compile time defined and unmutable and function as symbols
  50:  *  for constant values. For simple cases those values are ascending integers
  51:  *  starting at 0, that don't need to be specified.
  52:  *  For more complex situations both the key (in OORex terms: index) and the value
  53:  *  (in OORexx: items) are provided as a 2-item array in the argument array.
  54:  *
  55:  *  One could think of this as a dynamic inplementation if the ::CONSTANT 
  56:  *  directive, as it seems there is no provision for that in the built-in classes
  57:  *
  58:  *  @version  0.8    
  59:  *
  60:  *  @author   Ruurd Idenburg (ruurd@idenburg.net)
  61:  *  
  62:  *  2024-10-27 Changed '~class~id' to 'isA'
  63:  *
  64:  **/
  65: ::CLASS Enumeration PUBLIC
  66: 
  67: ::METHOD of PUBLIC CLASS
  68: -- get the enum arguments as an array
  69:   if arg(1)~isA(.String)
  70: -- case a. above 
  71:     then do
  72:       args = arg(1,'A')
  73: -- creation will generate the ascending integer sequence
  74:       simple = .true
  75:     end
  76:     else do 
  77:       if arg(1)~isA(.Array) & arg(1)[1]~isA(.Array) then do
  78: -- case c. above
  79:         args = arg(1)
  80:       end
  81:       else do
  82: -- case b. above
  83:         args = arg(1,'A')
  84:       end
  85: -- creation does not need the provide the values
  86:       simple = .false
  87:     end
  88: -- create the supporting table, caseless, as keys/indexes should be
  89: -- unique and case differences would make it error prone   
  90:   table = .caselessStringTable~new
  91: -- create an instance of this class
  92:   me = self~new
  93: -- give access to the table for the instance
  94:   me~enum = table
  95: -- preset the simpleness (one or two things per argument)
  96: --  simple = .false
  97: -- do we have a 2-item array per argument
  98: --  if args[1]~class~id='String' then simple=.true
  99:   loop arg=1 to args~last
 100: -- if sparse item iterate the loop
 101:   if \args~hasIndex(arg) then iterate
 102:   if simple then do
 103: -- get key, set index of the key minus 1 as value
 104:       key = args[arg]
 105:       value = args~index(key)-1
 106:     end
 107: -- get key and value from the argument array
 108:     else do
 109:       key = args[arg][1]
 110:       value = args[arg][2]
 111:     end
 112: -- and store the map member  
 113:     table[key]= value
 114:   end
 115: return me
 116: 
 117: ::ATTRIBUTE enum PRIVATE
 118: 
 119: ::METHOD '[]'
 120:   use strict arg key
 121: return self~enum[key]
 122: 
 123: /**
 124:  * The next 3 methods forward the message to the embedded
 125:  * caselessStringtable, that will return it's result'
 126:  **/
 127: ::METHOD items
 128: return self~enum~items
 129: 
 130: ::METHOD allindexes
 131: return self~enum~allindexes
 132: 
 133: ::METHOD allitems
 134: return self~enum~allitems
 135: 
 136: /**
 137:  * Method: unknown
 138:  *
 139:  * Allows to use the enum symbol to be used as a message
 140:  *
 141:  * @param string - the method name of the message
 142:  *
 143:  * @param array - an array with the original arguments
 144:  *
 145:  * @returns result  - the result of the forwarded method
 146:  *                    if valid method for the enum otherwise
 147:  *                    raises a syntax error.
 148:  **/
 149: ::METHOD unknown PRIVATE
 150:   use strict arg methodName, rest
 151: -- Make sure there is an index with the methodName
 152:   if self~enum~hasIndex(methodName) 
 153:     then return self~enum[methodName~upper]
 154: -- if not raise a syntax error
 155:     else raise syntax 97.001 array(self,methodName)
 156: exit  
 157: 
 158: ::REQUIRES 'caselessStringTable.cls'
All content © Ruurd Idenburg, 2007–2025, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on my on server at my home, falling under Dutch (privacy) laws.

This page updated on Wed, 28 May 2025 10:38:18 +0200.