ooRexx logo
   1: #!/usr/bin/env rexx
   2: /**
   3:  * A stringTable subclass that will support indexes of one word
   4:  * strings in any case (lower- upper- or mixed-case) and treat
   5:  * them as being the same when processing.
   6:  * ----------------------------------------------------------------
   7:  * Originally by Ruurd J. Idenburg 
   8:  * 
   9:  * No copyright, no licence, no guarantees or warrantees, be it 
  10:  * explicit, implicit or whatever. Usage is totally and completely 
  11:  * at the users own risk, the author shall not be liable for any
  12:  * damages whatsoever, for any reason whatsoever.
  13:  * 
  14:  * Please keep this comment block intact when modifying this code
  15:  * and add a note with date and a description.
  16:  * ----------------------------------------------------------------
  17:  * 2023/02/08 - Initial version requires ooRexx version 5.0.0 or 
  18:  *              later
  19:  * 2023/04/02 - Added catering for multi-word indexes by removing
  20:  *              the spaces between words when processing them (rji)
  21:  * 2023/05/04 - Added a (perhaps) more common example (rji)
  22:  * 2023/05/05 - Removed unneccesary exit statements in method
  23:  *              definitions (rji)  
  24:  *
  25:  */----------------------------------------------------------------
  26: 
  27: -- A simple sample
  28: cst = .caselessStringTable~new
  29: say "HELLO =>" cst~hello
  30: cst["Blonde On Blonde"] = "An album by Bob Dylan"
  31: cst~blonde = "My Hair"
  32: --say cst~allIndexes
  33: say "blond On Blonde => "cst["blonde On blonde"]
  34: say "Blonde =>" cst["Blonde"]
  35: say "Real indexes =>" cst~makeArray~toString(,", ")
  36: say "Index BLONDE ONBLONDE =>" cst~hasIndex("BLONDE ONBLONDE")
  37: say "Removing bLoNdE =>" cst~remove("bLoNdE")
  38: say "-"~copies(40)
  39: -- A more common (perhaps) sample
  40: memberList = .routines~createMemberList~call
  41: say "Actual indexes:" memberList[0]~allIndexes~sort~toString(,",  ")
  42: say "Used indexes..: ~first, ~last, ~middle" 
  43: say "-"~copies(40)
  44: do m over memberList
  45:   if m~middle==.nil
  46:     then say m~last"," m~first"," "middle name to be done"
  47:     else say m~last"," m~first"," m~middle
  48: end
  49: say "-"~copies(40)
  50: 
  51: /**
  52:  * Do not execute above code when invoked via a "::requires" directive
  53:  */
  54: ::options noprolog
  55: 
  56: /**
  57:  * All indexes are maintained in the .caselessStringTable superclass
  58:  * (i.e the .stringTable class). All methods with an index as argument
  59:  * are first checked for a caseless match before being forwarded to
  60:  * the superclass .stringTable methods.
  61:  */
  62: ::class "caselessStringTable" public subclass "stringTable"
  63: 
  64: /**
  65:  * Just let the superclass initiate the instance
  66:  */
  67: ::method "init"
  68:   self~init:super
  69: exit
  70: 
  71: /**
  72:  * Will check if there is already an index exactly the same in mixed- 
  73:  * or lower- or upper-case and return the matched index, otherwise
  74:  * will return the index given as the parameter.
  75:  */
  76: ::method "caselessIndex" private
  77:   use strict arg key
  78: /**
  79:  * Make sure the index will be one word only
  80:  */
  81:   key = key~space(0)
  82:   tmpString = self~makeArray~toString(," ")
  83:   wp = tmpString~caselessWordPos(key)
  84:   if wp=0
  85:     then tableIndex = key
  86:     else tableIndex = tmpString~word(wp)
  87: return tableIndex
  88: 
  89: /**
  90:  * This is the same as method "at", so let the"at' method handle it
  91:  */ 
  92: ::method "[]"
  93:   forward to (self) message ("at")
  94: exit
  95: 
  96: /**
  97:  * This the same method as "put", so let the "put' method handle it
  98:  */
  99: ::method "[]="
 100:   forward to (self) message ("put")
 101: exit
 102: 
 103: /**
 104:  * Same as the super class, but with the caseless match
 105:  * for it's indexes.
 106:  */ 
 107: ::method "at"
 108:   use strict arg key
 109:   index = self~caselessIndex(key)
 110: return self~at:super(index)
 111: 
 112: /**
 113:  * Same as the super class, but with the caseless match
 114:  * for it's indexes.
 115:  */ 
 116: ::method "hasIndex"
 117:   use strict arg key
 118:   index = self~caselessIndex(key)
 119: return self~hasIndex:super(index)  
 120: 
 121: /**
 122:  * Same as the super class, but with the caseless for it's
 123:  * indexes.If a caseless match exists the item value will be
 124:  * updated. If no match is found the index will be as provided.
 125:  */ 
 126: ::method "put"
 127:   use strict arg value, key
 128:   index = self~caselessIndex(key)
 129:   self~put:super(value, index)
 130: exit
 131: 
 132: /**
 133:  * Same as the super class, but with the caseless match
 134:  */ 
 135: ::method "remove"
 136:   use strict arg key
 137:   index = self~caselessIndex(key)
 138: return self~remove:super(index)
 139: 
 140: /**
 141:  * The "unknown" method allows processing as for an ooRexx standard
 142:  * .stringTable, like myCaselessStringtable~firstName="Mike"
 143:  */
 144: ::method "unknown"
 145:   use arg key, args
 146:   index = self~caselessIndex(key~strip('T','='))
 147:   if key~endsWith("=")
 148:     then self~put:super(args[1],index)
 149:     else return self~at:super(index)
 150: exit
 151: 
 152: /**
 153:  * Following are the methods to support the .stringTable "ENTRY" methods.
 154:  * I have not tested these.
 155:  */
 156: ::method "setEntry"
 157:   use strict arg key, value=.nil
 158:   index = self~caselessIndex(key)
 159:   self~setEntry:super(index, value)
 160: exit
 161: 
 162: ::method "entry"
 163:   use strict arg key
 164:   index = self~caselessIndex(key)
 165: return self~entry:super(index)
 166: 
 167: ::method "hasEntry"
 168:   use strict arg key
 169:   index = self~caselessIndex(key)
 170:   return self~hasEntry:super(index)  
 171: exit
 172: 
 173: ::method "removeEntry"
 174:   use strict arg key
 175:   index = self~caselessIndex(key)
 176: return self~removeEntry:super(index)
 177: 
 178: ::routine createMemberList
 179:   members = (("Zimmerman", "Robert", "Allen"),("Zappa","Frank",),("Cale","J.J.",),("Clapton","Eric","Patrick"))
 180:   memberList = .list~new
 181:   do m over members
 182:     member = .caselessStringTable~new
 183:     member["Last"] = m[1] 
 184:     member~first = m[2]
 185:     member["middle"] = m[3]
 186:     memberList~append(member)
 187:   end
 188: return memberList 
 189: 
 190: 
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, 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 a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on by Ruurd Idenburg.