On 12.03.2025 19:28, Gilbert Barmwater wrote:

Rather than just including the code for the two 'from' class methods, I have attached a file that you can use via ::requires stemarray.cls or, if you are in rexxtry, call stemarray.cls as I assume you might want to try them out.  This file contains the mixin classes and the sub-classes which would not be needed if the methods were part of the orderedCollection and stem classes.  Because of the sub-classing, the names are .xrray and .xtem - the first letter of the super class being replaced by x.  I will have more to say about this as part of my Symposium presentation.

The code is pretty well commented but I should point out that when a stem instance is to be converted, there exists the possibility that it is sparse, i.e. an expected tail is missing.  E.g. cv.0 = 3; cv.1 = 'Gil'; cv.3 = 'Rony' (no cv.2). I allow for both possibilities for the resulting array - ignore the missing tail so that the array only has 2 items or supply the 'default' stem value for any missing tails.  The choice is controlled by the presence/absence of a second argument.  The default is to NOT have the array include the missing tails on the assumption that what is important is the sequence of the items.  Two possible errors are raised - one if the argument is not the right type (a string for example) and the other if the input is a stem that has an invalid tail (not a positive integer or zero).  Finally, if a stem instance has a zero tail, that value will determine the (maximum) number of array items (any tails greater than the zero tail are discarded).

For the other 'from' method (converting to a stem), a third (optional) argument is supported which corresponds to the (optional) first argument of the stem class 'new' method that supplies the derived name of compound variables.  The previous comments apply to this method as well in regard to sparse stems and error reporting.

One final note that applies to both methods and relates to array instances only.  Of the four ordered collection classes, array is the only one that can be sparse - missing an index. Again, the assumption is that the sequence is what is important so missing indexes are ignored; a sparse array will NEVER be output.

Here are some examples showing the basic syntax:
nm. = .xtem~from(names) where names is an array   or
names = .xrray~from(nm.)   to go the other direction

Questions and comments are encouraged.

Thank you for sharing!

As an example says more than thousands words, here a program defining a stem array which gets used for conversion to the different orderedCollection classes taking advantage of Gil's "stemarray.cls":

   say "using a stem array named 's.':" s.='--> not set <--' -- default value 
s.1='hi (1)' s.3='hi
   (3)' s.0=5 -- tails '2' and '4', '5' are missing say "s.0="s.0", s.' default value: 
"""s."""" do
   i=1 to s.0 say " s."i":" s.i end say "-"~copies(79) say call demoFromStem s. 
*::requires
   "stemarray.cls" **-- Gil's implementation* ::routine demoFromStem say .line":" 
.context~name "-
   begin" use arg s. say say "-- pass 1 -- not supplying a second argument ..." 
say do clz over
   .xrray, .xist, .xueue, .xircularQueue, .xtem obj=clz~from(s.) call dump obj end 
say say "-- pass
   2 -- supplying a second argument ..." say do clz over .xrray, .xist, .xueue, 
.xircularQueue,
   .xtem obj=clz~from(s., "some value") call dump obj end say .line":" .context~name 
"- done."
   ::routine dump use arg coll say "dumping a" coll~class~id":" -- show type of 
received coll do
   counter c with index idx item val over coll say " #" c": index="pp(idx) 
"val:" pp(val) end say
   "---" ::routine pp return "["arg(1)"]"

Here the output:

   rexx G:\test\orx\stem\20250312\test_sa.rex using a stem array named 's.': 
s.0=5, s.' default
   value: "--> not set <--" s.1: hi (1) s.2: --> not set <-- s.3: hi (3) s.4: --> 
not set <-- s.5:
   --> not set <-- 
-------------------------------------------------------------------------------
   18: DEMOFROMSTEM - begin -- pass 1 -- not supplying a second argument ... 
dumping a XRRAY: # 1:
   index=[1] val: [hi (1)] # 2: index=[2] val: [hi (3)] --- dumping a XIST: # 
1: index=[0] val: [hi
   (1)] # 2: index=[1] val: [hi (3)] --- dumping a XUEUE: # 1: index=[1] val: 
[hi (1)] # 2:
   index=[2] val: [hi (3)] --- dumping a XIRCULARQUEUE: # 1: index=[1] val: [hi 
(1)] # 2: index=[2]
   val: [hi (3)] --- dumping a Stem: # 1: index=[0] val: [5] # 2: index=[3] 
val: [hi (3)] # 3:
   index=[1] val: [hi (1)] --- -- pass 2 -- supplying a second argument ... 
dumping a XRRAY: # 1:
   index=[1] val: [hi (1)] # 2: index=[2] val: [--> not set <--] # 3: index=[3] 
val: [hi (3)] # 4:
   index=[4] val: [--> not set <--] # 5: index=[5] val: [--> not set <--] --- 
dumping a XIST: # 1:
   index=[0] val: [hi (1)] # 2: index=[1] val: [--> not set <--] # 3: index=[2] 
val: [hi (3)] # 4:
   index=[3] val: [--> not set <--] # 5: index=[4] val: [--> not set <--] --- 
dumping a XUEUE: # 1:
   index=[1] val: [hi (1)] # 2: index=[2] val: [--> not set <--] # 3: index=[3] 
val: [hi (3)] # 4:
   index=[4] val: [--> not set <--] # 5: index=[5] val: [--> not set <--] --- 
dumping a
   XIRCULARQUEUE: # 1: index=[1] val: [hi (1)] # 2: index=[2] val: [--> not set 
<--] # 3: index=[3]
   val: [hi (3)] # 4: index=[4] val: [--> not set <--] # 5: index=[5] val: [--> 
not set <--] ---
   dumping a Stem: # 1: index=[0] val: [5] # 2: index=[2] val: [--> not set 
<--] # 3: index=[1]
   val: [hi (1)] # 4: index=[5] val: [--> not set <--] # 5: index=[4] val: [--> 
not set <--] # 6:
   index=[3] val: [hi (3)] --- 36: DEMOFROMSTEM - done.

---

Here Gil's code ("stemarray.cls") syntax highlighted (using IntelliJ with the 
ooRexx plugin):

   -- This package adds the 'from' class method to the ordered collection 
classes -- and the stem
   class. ::class orderedCollectionPlus mixinclass Object ::method from class 
-- Expects one
   argument that is either an instance of an ordered collection or -- a stem 
with only positive
   integer tails, w/ or w/o a .0 tail value. -- An optional second argument w/ 
any value indicates
   sparse stems should be -- expanded to include all tails use arg inCollection 
sparse? = arg(2, O)
   select when inCollection~isA(.orderedCollection) then do if 
self~isSubClassOf(.circularQueue)
   then -- size required for instance of .circularQueue instance = 
self~new(inCollection~items)
   else instance = self~new() instance~appendAll(incollection) end when 
inCollection~isA(rexx:stem)
   then do tails = inCollection~allIndexes~sort loop aTail over tails -- tails 
must be whole
   numbers >= 0 if datatype(aTail, 'W'), atail >= 0 then nop else do err_msg = 
'Stem tails must be
   positive integers or zero;' - 'found' aTail raise syntax 93.900 array 
(err_msg) end end if
   tails[1] = 0 then do -- if the .0 tail exists, use it stemSize = 
inCollection[0] tails =
   tails~section(2) -- remove tail 0 end else -- otherwise use the largest tail 
stemSize =
   tails~lastItem if self~isSubClassOf(.circularQueue) then -- size required 
for instance of
   .circularQueue instance = self~new(stemSize) else instance = self~new() -- 
even if the stem is
   sparse, the new instance will NOT be sparse if sparse? then -- only include 
tail values that are
   defined loop idx over tails while idx <= stemsize 
instance~append(inCollection[idx]) end else
   loop idx = 1 to stemSize -- include all possible tail values 
instance~append(inCollection[idx])
   end end otherwise err_msg = 'Invalid argument; must be an ordered 
collection' - 'instance or a
   stem with positive integer tails; found' - inCollection~objectName raise 
syntax 93.900 array
   (err_msg) end return instance ::class stemPlus mixinclass Object ::method 
from class -- Expects
   one argument that is either an instance of an ordered collection or -- a 
stem with only positive
   integer tails, w/ or w/o a .0 tail value. -- An optional second argument w/ 
any value indicates
   sparse stems should be -- expanded to include all tails -- If a third 
argument is present it is
   used as the stemName of the new instance use arg inCollection, , stemName='' 
--trace ?i sparse?
   = arg(2, O) select when inCollection~isA(.orderedCollection) then do newStem 
=
   rexx:stem~new(stemName) tail = 0 loop anItem over inCollection tail += 1 
newStem[tail] = anItem
   end newStem[0] = tail end when inCollection~isA(rexx:stem) then do newStem =
   rexx:stem~new(stemName) tails = inCollection~allIndexes~sort loop aTail over 
tails -- tails must
   be whole numbers >= 0 if datatype(aTail, 'W'), atail >= 0 then nop else do 
err_msg = 'Stem tails
   must be positive integers or zero;' - 'found' aTail raise syntax 93.900 
array (err_msg) end end
   if tails[1] = 0 then do -- if the .0 tail exists, use it stemSize = 
inCollection[0] tails =
   tails~section(2) -- remove tail 0 end else -- otherwise use the largest tail 
stemSize =
   tails~lastItem newStem[0] = stemSize -- set the size if sparse? then -- the 
new stem will be
   sparse if the stem is sparse loop idx over tails while idx <= stemsize 
newStem[idx] =
   inCollection[idx] end else -- the new stem won't be sparse even if the stem 
is sparse loop idx =
   1 to stemSize newStem[idx] = inCollection[idx] end end otherwise err_msg = 
'Invalid argument;
   must be an ordered collection' - 'instance or a stem with positive integer 
tails; found' -
   inCollection~objectName raise syntax 93.900 array (err_msg) end return 
newStem /* subclass names
   are the same as the name of their class with the first character replaced by 
x */ ::class xrray
   subclass array public inherit orderedCollectionPlus ::class xist subclass 
list public inherit
   orderedCollectionPlus ::class xueue subclass queue public inherit 
orderedCollectionPlus ::class
   xircularQueue subclass circularQueue public inherit orderedCollectionPlus 
::class xtem subclass
   stem public inherit stemPlus

---

---rony



_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to