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.
Gil
On 3/11/2025 9:25 PM, Gilbert Barmwater wrote:
This project started many years ago - the earliest file I have located
was dated 21 Sept. 2009 - and was initially only concerned with
converting one type of ordered collection to another. Each of the
four classes - array, list, queue and circularQueue - provided a
different "view" of a sequence of items (and, hence, different methods
to operate on them) but they all shared the property that the order of
the items was what was significant. I thought it would be useful to
be able to easily change "views" and came up with the idea of a 'from'
class method, similar to the 'of' class method but taking an ordered
class instance as its argument instead of an enumeration of the
items. The code was relatively straight forward but making the 'from'
method available took some time. I finally settled on creating a
mixin class with the single 'from' class method and then four
sub-classes that inherited from the mixin class.
As with all projects, they are never 'finished' and this one wasn't
either. I realized that stem arrays are often used in place of one of
the four ordered collection classes and that converting to or from a
stem array would also be useful. Allowing my 'from' method to take a
stem array instance as its argument was the next step and it solved
the conversion "from" part but to allow conversion "to" a stem array
required a different approach. I experimented with a 'toStem'
(instance) method but wasn't happy with the asymmetry so I created a
'from' class method for the stem class with the same syntax. This
required another mixin class and another sub-class but it worked.
As this solution provides the functionality requested in the original
post, I offer it as a way to not "reinvent the wheel" so to speak. In
my next post, I will include the code for the two 'from' methods and
provide some (additional) comments on how it works and some examples
of its use. Stay tuned...
On 3/11/2025 9:27 AM, Gilbert Barmwater wrote:
Thanks for the interest in my approach. My plan is to post the code
- two class methods, both named 'from' - to this list with a better
description of where they are added and some examples of how one
might use this functionality. I'm hoping to do so later today
depending on the time I have available.
Gil
On 3/11/2025 8:26 AM, Josep Maria Blasco wrote:
Hi Rony,
Missatge de Rony G. Flatscher <rony.flatsc...@wu.ac.at> del dia dl.,
10 de març 2025 a les 17:44:
Hi Josep Maria,
On 09.03.2025 14:40, Josep Maria Blasco wrote:
Missatge de Rony G. Flatscher <rony.flatsc...@wu.ac.at> del dia
dg., 9 de març 2025 a les 14:04:
(cut)
1a) In order to create an ooRexx array from a stem
array the following method should be added to the stem
class:
makeArrayFromStemArray
This name makes it clear that a stem array is to be
processed and that the resulting array should not have
the stem value with the tail 0.
(The existting stem method makeArray continues to
create an array that represents all tails of a stem,
including a tail with the value 0.)
I'm not sure that using "makeXXX" for the message names is
a good idea, because the request method of the Object
class uses the "make" pattern for class conversions.
Yes, that is the reason why using that name.
Ah, but a class called "ArrayFromStemArray" does not exist, and
that breaks the "make" semantics. Rexxref 5.4.1.18 "request"
says "Any conversion method *must return an object of the
requested class*. For example, makeArray must return an array"
(emphasis mine). But, since there is no such thing as an
ArrayFromStemArray class, this could be misleading.
Yes. The conversion method must start with "make" and be
followed by the classid (a string) supplied as argument to the
.Object's request method.
This protocol could be used for creating an array from a stem
(by implementing a method "make" || supplied_classId_as_arg,
however, there is already a makearray method defined for stem.
Hence the first idea to add the variant to the name of the
conversion method yielding "makeArrayFromStemArray". The reason
being that .Object's request method does only accept the classid
argument and by using another name that includes the intent
("fromStemArray") one could add another make conversion method
to the stem class. However, I concur that a) the name becomes
too long and b) probably "classid" should be an existing
classid. :) Then it becomes possibel to change the name of the
method tonot start with "make" hence not adhering to the request
protocol.
Exactly!
In the meantime Gil's idea seems to be interesting.
I like it too. Very elegant, simple and easy to remember.
Josep Maria
---rony
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel
--
Gil Barmwater
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel
--
Gil Barmwater
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel
--
Gil Barmwater
-- 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
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel