Narrowing assignments and class tests
As discussed in "Polymorphism", Sirius Mods Version 6.9 introduced class test and narrowing assignment capabilities to the Janus SOAP ULI. As stated in that discussion, class tests and narrowing assignments should not be done lightly and, in fact, should be avoided as much as possible. For this reason, by default, class tests and narrowing assignments are not allowed for any class.
If class tests or narrowing assignments are unavoidable for a class, however, an
Allow Narrow clause must be placed in the Public block of that
For example, the
Mammal class could have the following:
class mammal public allow narrow variable weight is float variable name is string len 32 variable home is string len 32 ... end public end class
Then, if you have a class
Marsupial that extends the
you could do something like the following:
%pouchy is object marsupial %furry is object mammal ... if %furry:name = 'Skippy' then %pouchy = %furry:(marsupial) end if
In this example, if earlier lines in the program did not make
%furry actually reference a
and it simply referenced a simple
Mammal object or, perhaps, some other
extension of class
Mammal (say object
Feline), the assignment of
%pouchy would fail and the request would be cancelled.
Working with a pseudo-method
As shown in the preceding example, narrowing assignment cannot be done by a simple assignment of object variables (
It has to be indicated by a pseudo-method consisting
of the target class name in parentheses.
The term pseudo-method is used because no actual code is executed in
(marsupial) operation and no transformation of the input
object is performed — if
%furry references a marsupial, the
operation would succeed, otherwise it would fail.
The narrowing pseudo-method will always fail if the source object is
With this syntax, you can string member names to a narrowing
For example, if the
Marsupial class in the above example had a
member, you can do something like this:
if %furry:name = 'Skippy' then print %furry:(marsupial):pouchSize end if
You can also pass a narrowing assignment pseudo-method output as a method parameter:
You can even do something as silly as this:
(marsupial) does a narrowing assignment of
an internal work variable.
(mammal)weight accesses the
Mammal base class
Weight via that variable.
Of course, the above is identical to:
with the exception that the silly example would cancel the request
%furry did not reference a marsupial.
It is worth emphasizing that the
(marsupial) and the
(mammal) in the above example serve two very different
(marsupial) indicates a narrowing assignment to an
(mammal) indicates selection of a member of a base class.
Using the Is Instance Of operator
You might want to do narrowing assignments on the basis of the
class of the object pointed to by an object variable.
In the above example,
%furry is declared as being a
but, via polymorphism, can be pointing at an object of some extension
class, including, of course, class
You can use the Is Instance Of keywords to
test whether the underlying object referenced by an object variable
is of a specific class.
The following is an example using Is Instance Of:
%pouchy is object marsupial %furry is object mammal ... if %furry is instance of marsupial then %pouchy = %furry:(marsupial) end if
In fact, you can perform class-specific processing based on such tests:
%furry is object mammal ... if %furry is instance of marsupial then %furry:home = 'Australia' end if
This kind of code is strongly discouraged, and it is a formula for long-term code maintainability problems. What will happen to the above code, for example, when used on an opossum, which is one of the few marsupials that doesn't necessarily live in Australia?
The Is Instance Of keywords must be followed by the name of a class
that is an extension class of the type of the object variable that
precedes the keywords.
Note: No system classes currently are Allow Narrow classes.