<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://m204wiki.rocketsoftware.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jeff</id>
	<title>m204wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://m204wiki.rocketsoftware.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jeff"/>
	<link rel="alternate" type="text/html" href="https://m204wiki.rocketsoftware.com/index.php?title=Special:Contributions/Jeff"/>
	<updated>2026-04-20T19:42:44Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://m204wiki.rocketsoftware.com/index.php?title=Intrinsic_classes&amp;diff=90</id>
		<title>Intrinsic classes</title>
		<link rel="alternate" type="text/html" href="https://m204wiki.rocketsoftware.com/index.php?title=Intrinsic_classes&amp;diff=90"/>
		<updated>2011-01-07T14:15:42Z</updated>

		<summary type="html">&lt;p&gt;Jeff: grammer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also:&lt;br /&gt;
*[[List of intrinsic Float methods]]&lt;br /&gt;
*[[List of intrinsic String methods]]&lt;br /&gt;
*[[List of intrinsic Unicode methods]]&lt;br /&gt;
===Definition of Intrinsic classes===&lt;br /&gt;
In “pure” [http://en.wikipedia.org/wiki/Object-oriented_programming object-oriented languages], all datatypes are objects, that is, all datatypes are&lt;br /&gt;
extension classes of some base object class. This means that even things that one&lt;br /&gt;
might not immediately think of as objects, such as character strings or numbers, are, in&lt;br /&gt;
fact, considered to be objects.&lt;br /&gt;
There are two aspects to the assertion that strings or numbers are objects:&lt;br /&gt;
*They are internally managed in exactly the same was as any other objects. That is, a string or numeric variable is actually a reference to an object that contains the string or numeric value, rather than itself directly containing the string or numeric value.&lt;br /&gt;
*They are syntactically identical to other objects. That is, the syntax for manipulating strings or numbers is the same as the syntax for manipulating other objects. More specifically, methods are applied to strings or numbers using the exact same syntax as when methods are applied to other objects.&lt;br /&gt;
Since the first aspect is concerned with the internal management of strings or numbers,&lt;br /&gt;
it is largely irrelevant from the perspective of a programmer using a “pure” object-&lt;br /&gt;
oriented language. In fact, many languages that profess to be “pure” actually “cheat,”&lt;br /&gt;
internally, and they special-case string and numeric data. They do so because string&lt;br /&gt;
and numeric data is so important, and so heavily used in all programming languages,&lt;br /&gt;
that insisting on not treating it specially (internally) is pedantry that has a cost in&lt;br /&gt;
performance. To see why, consider a statement that adds two numbers together (the&lt;br /&gt;
language for the example is, of course, User Language):&lt;br /&gt;
       %x is float&lt;br /&gt;
       %y is float&lt;br /&gt;
        ...&lt;br /&gt;
       %x = %y + 13&lt;br /&gt;
Insisting that numbers are no different from any other object means that this statement&lt;br /&gt;
must get the value referenced by %y, add it to the number referenced by the literal “13”,&lt;br /&gt;
create a new Float instance and set %x to reference that new instance. Clearly, this&lt;br /&gt;
would be less efficient than taking the number in %y, adding 13 to it and setting %x to&lt;br /&gt;
the result. Fortunately, the way this is actually done is purely an under-the-covers                    &lt;br /&gt;
implementation issue, so one can always pretend that “pure” object-oriented processing&lt;br /&gt;
is being used.&lt;br /&gt;
This is so because numbers and strings are an example of a special class of objects&lt;br /&gt;
called immutable objects. Immutable objects, as the name suggests, cannot be&lt;br /&gt;
changed once they are created. To illustrate the difference between immutable objects&lt;br /&gt;
and mutable objects, consider two variables:&lt;br /&gt;
      %count        is float&lt;br /&gt;
      %account      is object bankAccount&lt;br /&gt;
If %account were set to a new object instance, it would not be surprising if, after it&#039;s set,&lt;br /&gt;
the object changed. For example, it wouldn&#039;t be surprising if the account balance for&lt;br /&gt;
%account changed, even if the change was done via a different variable:&lt;br /&gt;
      print %account:balance&lt;br /&gt;
      %myAccount = %account&lt;br /&gt;
      %myAccount:addToBalance(23)&lt;br /&gt;
      print %account:balance&lt;br /&gt;
In this example, it is expected that the balance displayed in the second Print statement&lt;br /&gt;
will be 23 greater than that displayed by the first.&lt;br /&gt;
On the other hand, given the following:&lt;br /&gt;
      print %count&lt;br /&gt;
      %myCount = %count&lt;br /&gt;
      %myCount:addToValue(23)&lt;br /&gt;
      print %count&lt;br /&gt;
It would be surprising for some operation on %myCount to have changed the value in&lt;br /&gt;
%count. In general, for variables that contain numeric or string values, one would only&lt;br /&gt;
expect the value to change when a new value is assigned to it. In fact, one would not&lt;br /&gt;
expect to see methods like AddToValue that modify the method object for a numeric&lt;br /&gt;
datatype.&lt;br /&gt;
More typical for a numeric datatype would be a method that manipulates the value and&lt;br /&gt;
produces a new value (object):&lt;br /&gt;
      %myCount =       %myCount:addToValue(23)&lt;br /&gt;
Although even pure object-oriented languages have special syntax for the common&lt;br /&gt;
operation of addition:&lt;br /&gt;
      %myCount =       %myCount + 23&lt;br /&gt;
Absence of methods that modify a value is what make a class immutable, and in “pure”&lt;br /&gt;
object-oriented languages, basic string and numeric datatypes are always immutable.&lt;br /&gt;
==Intrinsic methods in User Language==&lt;br /&gt;
User Language is a legacy programming language for which object-oriented capabilities&lt;br /&gt;
are a relatively recent addition. So, one might expect that strings and numbers are not&lt;br /&gt;
maintained internally as objects, since their existence pre-dates objects. This is in fact&lt;br /&gt;
the case, though as was shown, this is largely irrelevant from a User Language&lt;br /&gt;
programmer&#039;s perspective, And even if object-oriented capabilities were present in User&lt;br /&gt;
Language from its inception, strings and numbers might have been special-cased for&lt;br /&gt;
efficiency anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;intrins_classes&amp;quot;&amp;gt;The intrinsic classes are:&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;Float&lt;br /&gt;
&amp;lt;dd&amp;gt;See the [[:Category:Intrinsic Float methods|Float methods]]&lt;br /&gt;
&amp;lt;dt&amp;gt;String&lt;br /&gt;
&amp;lt;dd&amp;gt;See the [[:Category:Intrinsic String methods|String methods]]&lt;br /&gt;
&amp;lt;dt&amp;gt;Unicode&lt;br /&gt;
&amp;lt;dd&amp;gt;See the [[:Category:Intrinsic Unicode methods|Unicode methods]]&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The benefits of object-oriented syntax in User Language==&lt;br /&gt;
Beyond the internal representation of strings and numbers, a distinction between User&lt;br /&gt;
Language and pure object-oriented languages was that the object:method syntax&lt;br /&gt;
was not used to manipulate strings and numbers; instead, strings and numbers were&lt;br /&gt;
manipulated via $functions. Sirius Mods 7.2 changed this to allow the object:method&lt;br /&gt;
syntax against string and numeric variables and constants.&lt;br /&gt;
The following code fragment illustrates how the same operation can be accomplished via&lt;br /&gt;
traditional $functions and via object-oriented syntax:&lt;br /&gt;
     %name         is string len 32&lt;br /&gt;
       ...&lt;br /&gt;
     print $len(%name)&lt;br /&gt;
     print %name:length&lt;br /&gt;
While this might not seem very significant, it provides considerable value:&lt;br /&gt;
*It allows User Language to be used as a “pure” object-oriented language. This might be especially appealing to programmers who were trained in a pure object-oriented language.&lt;br /&gt;
*It provides the benefit that expressions can generally be read in the natural left-to-right manner rather than the inside-to-outside manner required to understand an expression coded with $functions.&lt;br /&gt;
*It provides capabilities to methods that operate on strings or numbers that are not available with $functions. These include support for named parameters and the ability to take objects as input parameters and to produce objects as results. While it would have been possible to extend $functions to have this same functionality (much as Sirius Mods provided callable $function support), it makes more sense to provide it using true object-oriented syntax. Given that this has now been done, it is unlikely that these capabilities will ever be added to $functions.&lt;br /&gt;
==Two generic intrinsic classes: string and numeric==&lt;br /&gt;
User Language traditionally allowed declarations of many different datatypes. These&lt;br /&gt;
included Strings of a specified length with a possible DP value, Fixed numerics (also&lt;br /&gt;
with a possible DP), and Float numerics. In addition, Sirius Mods provided support for&lt;br /&gt;
Longstring datatypes. And images provide support for a variety of additional datatypes,&lt;br /&gt;
including packed and zoned formats. Essentially, however, there are two categories of&lt;br /&gt;
datatypes in User Language: string and numeric. In User Language one can easily&lt;br /&gt;
assign values from one datatype to another, even between numeric and string types.&lt;br /&gt;
This is intuitive and useful. Typically, in the “real world” one doesn&#039;t distinguish between&lt;br /&gt;
the string representation of a number and its numeric value used for calculation.&lt;br /&gt;
Similarly, except for performance purposes and, perhaps, value limits, one is typically&lt;br /&gt;
not concerned about how a value is stored internally.&lt;br /&gt;
&lt;br /&gt;
This is not the case in some “pure” object-oriented languages where the paradigm of&lt;br /&gt;
strong-datatyping is extended to numeric and string datatypes. This means that if one&lt;br /&gt;
wants to display the value of a numeric variable, one must explicitly convert it to a string&lt;br /&gt;
(since what one displays is a string). Similarly, if one wishes to do a calculation using a&lt;br /&gt;
value in a string (perhaps read from an external data source), one must explicitly convert&lt;br /&gt;
the string to a number. It is asserted here that strong-datatyping for strings and numbers&lt;br /&gt;
is a mistake, allowing some vision of purity to prevent programmers from doing&lt;br /&gt;
something completely natural (treating numbers as strings, and strings as numbers) and&lt;br /&gt;
something that is done hundreds of times in any program of any size. This view is&lt;br /&gt;
reinforced by the fact that the general industry trend is away from strong-datatyping for&lt;br /&gt;
strings and numbers and toward implicit conversion between these types.&lt;br /&gt;
&lt;br /&gt;
It is worth pointing out, however, that loose-datatyping between strings and numbers&lt;br /&gt;
does not imply loose-datatyping between strings and numbers and other classes. That&lt;br /&gt;
is, there are generally no implicit conversions of strings or numbers to or from non-string,&lt;br /&gt;
non-numeric objects.&lt;br /&gt;
&lt;br /&gt;
Because loose-datatyping and the existing User Language datatypes work quite well in&lt;br /&gt;
facilitating rapid development of reasonably tight and efficient code, the Janus SOAP&lt;br /&gt;
ULI support for methods against string and numeric types does not add any new&lt;br /&gt;
datatypes to User Language. And, because of loose-datatyping, the numeric and string&lt;br /&gt;
methods can be applied to any of the standard User Language string and numeric&lt;br /&gt;
datatypes. Because they apply to these intrinsic User Language datatypes, these&lt;br /&gt;
methods are called intrinsic methods.&lt;br /&gt;
&lt;br /&gt;
Intrinsic methods can be further classified into these subsets:&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;Float&amp;lt;dd&amp;gt;Methods that perform numeric manipulation on values in Model 204&#039;s Float format.&lt;br /&gt;
&amp;lt;dt&amp;gt;Fixed&amp;lt;dd&amp;gt;Methods that perform numeric manipulation on values in Model 204&#039;s Fixed format (with an assumed DP of 0).&lt;br /&gt;
&amp;lt;dt&amp;gt;String&amp;lt;dd&amp;gt;Methods that perform string manipulation, with Longstring capability assumed.&lt;br /&gt;
&amp;lt;dt&amp;gt;Unicode&amp;lt;dd&amp;gt;Methods that perform Unicode string string manipulation, return Unicode results, or are based on the Unicode tables.&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Float intrinsic class can really be thought of as a generic numeric class, as it is a&lt;br /&gt;
convenient way of representing both integer and decimal data. This is different from&lt;br /&gt;
most other programming languages where a Float datatype suffers from inconvenient&lt;br /&gt;
behavior, especially for decimal numbers.&lt;br /&gt;
&lt;br /&gt;
The Float class is so convenient that all numeric parameters to system methods and&lt;br /&gt;
$functions are treated as Float parameters. Also, because of the convenience of the&lt;br /&gt;
Float class, there are currently no methods in the Fixed class.&lt;br /&gt;
As such, the intrinsic methods can be thought of broadly as belonging to two intrinsic&lt;br /&gt;
classes: the Numeric class and the String class. These classes behave largely as if their&lt;br /&gt;
inputs were User Language Float and Longstring datatypes, respectively. That is, for all&lt;br /&gt;
intents and purposes, the following are true:&lt;br /&gt;
*Any non-Float values, including Unicode, are converted to Float values before being processed by a Numeric method. This includes the conversion of any non-numeric strings into 0 that occurs in other User Language contexts that take a numeric input.&lt;br /&gt;
*For the purposes of truncation and the With operation, all String method string inputs or outputs behave as longstrings.&lt;br /&gt;
==Strings and numbers as method objects==&lt;br /&gt;
The term &amp;amp;ldquo;method object&amp;amp;rdquo; (or &amp;amp;ldquo;intrinsic method object&amp;amp;rdquo;) is used for                                     &lt;br /&gt;
the value or variable to which an intrinsic method is applied,                                                                  &lt;br /&gt;
even though the value or variable isn&#039;t really an object.                                                                       &lt;br /&gt;
This is justified because, as noted above, strings and numbers can be considered                                                &lt;br /&gt;
immutable objects, regardless of their history or internal representation.                                                      &lt;br /&gt;
                                                                                                                                &lt;br /&gt;
For example, in the following case,                                                                                             &lt;br /&gt;
&amp;lt;tt&amp;gt;%str&amp;lt;/tt&amp;gt; is the intrinsic method object for the &amp;lt;tt&amp;gt;Length&amp;lt;/tt&amp;gt; method:                                                    &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
    %str   is string len 32                                                                                                     &lt;br /&gt;
     ...                                                                                                                        &lt;br /&gt;
    print %str:Length                                                                                                           &lt;br /&gt;
&amp;lt;/pre&amp;gt;                                                                                                                          &lt;br /&gt;
                                                                                                                                &lt;br /&gt;
Intrinsic methods can be applied to constants, in addition to variables.                                                        &lt;br /&gt;
For example, the following assigns the length of the string literal                                                             &lt;br /&gt;
&amp;amp;ldquo;Whatever&amp;amp;rdquo; to %x:                                                                                                   &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
    %x = &#039;Whatever&#039;:length                                                                                                      &lt;br /&gt;
&amp;lt;/pre&amp;gt;                                                                                                                          &lt;br /&gt;
Intrinsic methods can take the output from another method,                                                          &lt;br /&gt;
intrinsic or not, as its input.                                                                                                 &lt;br /&gt;
For example, the following uses the Right method (which gets the                                                                &lt;br /&gt;
rightmost characters of a string) against the output of a Stringlist                                                            &lt;br /&gt;
Item method:                                                                                                                    &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
    %list    is object stringlist                                                                                               &lt;br /&gt;
     ...                                                                                                                        &lt;br /&gt;
    %value = %list:item(%i):right(8)                                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;                                                                                                                          &lt;br /&gt;
Since it is unnecessary to explicitly specify the Item method for                                                               &lt;br /&gt;
a Stringlist, the above can also be written as:                                                                                 &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
    %list    is object stringlist                                                                                               &lt;br /&gt;
     ...                                                                                                                        &lt;br /&gt;
    %value = %list(%i):right(8)                                                                                                 &lt;br /&gt;
&amp;lt;/pre&amp;gt;                                                                                                                          &lt;br /&gt;
Intrinsic methods can also be applied to User Language Image and Screen items:                                                                &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
    image michigan                                                                                                              &lt;br /&gt;
       romulus   is string len 32                                                                                               &lt;br /&gt;
       ...                                                                                                                      &lt;br /&gt;
    end image                                                                                                                   &lt;br /&gt;
     ...                                                                                                                        &lt;br /&gt;
    %value = %michigan:romulus:right(8)                                                                                         &lt;br /&gt;
&amp;lt;/pre&amp;gt;                                                                                                                          &lt;br /&gt;
And Intrinsic methods can be applied to the output from a $function:                                                           &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
    %seconds = $time:right(2)                                                                                                   &lt;br /&gt;
&amp;lt;/pre&amp;gt;                                                                                                                          &lt;br /&gt;
Intrinsic methods can even be applied to the results of expressions:                                                            &lt;br /&gt;
&amp;lt;pre&amp;gt;                                                                                                                           &lt;br /&gt;
     ...                                                                                                                        &lt;br /&gt;
    %value = (%tweedledum with %tweedledee):right(8)                                                                            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Automatic “implicit” conversion of intrinsic values==&lt;br /&gt;
As with other methods, the colon that separates the intrinsic method object from the method&lt;br /&gt;
name can be optionally preceded or followed by spaces. This could be done to enhance&lt;br /&gt;
readability, or even to split a long line. The following four statements are all equivalent:&lt;br /&gt;
     %value     = %list:item(%i):right(8)&lt;br /&gt;
     %value     = %list: item(%i): right(8)&lt;br /&gt;
     %value     = %list :item(%i) :right(8)&lt;br /&gt;
     %value     = %list : item(%i) : -&lt;br /&gt;
                          right(8)&lt;br /&gt;
As with most other uses of intrinsic variables or values, if the method object is of a&lt;br /&gt;
different type than the datatype on which the method operates, the input value is&lt;br /&gt;
automatically converted into the target datatype. For example, the expression 7/3&lt;br /&gt;
clearly produces a numeric value, but the Left method operates on strings. So, in the&lt;br /&gt;
statement:&lt;br /&gt;
      %i   = (7/3):left(4)&lt;br /&gt;
the result of the division is converted into a string and then passed to Left, which&lt;br /&gt;
produces 2.33 as its result.&lt;br /&gt;
Because of this automatic conversion, the specific class (String, Float, Unicode) of an&lt;br /&gt;
intrinsic method cannot be determined from the datatype of its method object. This&lt;br /&gt;
means that the class must be determined only from the name of the method, which&lt;br /&gt;
means that method names must be unique among all intrinsic classes (that is, among&lt;br /&gt;
String, Float, and Unicode). For example, there may not be a Length method in both the&lt;br /&gt;
String and Float intrinsic classes. In the case of Length, the method is an intrinsic String&lt;br /&gt;
method, there is no comparable Float method, and UnicodeLength is the comparable&lt;br /&gt;
Unicode method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; Because some EBCDIC characters are not translatable to Unicode, and vice&lt;br /&gt;
versa, automatic conversions involving Unicode values may cause request cancellation.&lt;br /&gt;
The explicit intrinsic conversion methods (like EbcdicToUnicode and EbcdicToAscii and&lt;br /&gt;
their counterparts UnicodeToEbcdic and AsciiToEbcdic), however, have a parameter (as&lt;br /&gt;
of Sirius Mods version 7.6) that lets you decode or encode untranslatable characters.&lt;br /&gt;
&lt;br /&gt;
==Intrinsic method syntax: special cases== &lt;br /&gt;
User Language is a legacy programming language that supports some unusual syntax.&lt;br /&gt;
Some of this syntax causes problems for the use of intrinsic methods,&lt;br /&gt;
as is described for the following three cases:&lt;br /&gt;
&lt;br /&gt;
===Intrinsic methods against database field names===&lt;br /&gt;
Field names have very loose naming rules, and names can contain colons&lt;br /&gt;
and spaces.&lt;br /&gt;
Because of this, a field name must be contained inside of parentheses&lt;br /&gt;
to be used as a method object.&lt;br /&gt;
For example, the field &amp;lt;tt&amp;gt;big fat greek field&amp;lt;/tt&amp;gt;&lt;br /&gt;
is used as the input to the intrinsic [[Substring (String function)|Substring]] method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    for each record in %recordset&lt;br /&gt;
       ...&lt;br /&gt;
       %value = (big fat greek field):substring(2, 3)&lt;br /&gt;
       ...&lt;br /&gt;
    end for&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Intrinsic methods against percent variables and images that have the same name===&lt;br /&gt;
User Language allows one to declare images and percent variables with the same name&lt;br /&gt;
in the same scope.&lt;br /&gt;
That is, inside a method, you can declare an image called &amp;lt;tt&amp;gt;holland&amp;lt;/tt&amp;gt;&lt;br /&gt;
and a %variable called &amp;lt;tt&amp;gt;%holland&amp;lt;/tt&amp;gt;.&lt;br /&gt;
References to items in the image and to the percent variable both start&lt;br /&gt;
with &amp;lt;tt&amp;gt;%holland&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    image holland&lt;br /&gt;
      ...&lt;br /&gt;
      factory   is float&lt;br /&gt;
      ...&lt;br /&gt;
    end image&lt;br /&gt;
     ...&lt;br /&gt;
    %holland   is string len 10&lt;br /&gt;
     ...&lt;br /&gt;
    %a = %holland:factory&lt;br /&gt;
     ...&lt;br /&gt;
    %a = %holland&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Historically, this has not been a problem because a percent variable&lt;br /&gt;
would never be followed by a colon.&lt;br /&gt;
However, with intrinsic methods, this is no longer the case.&lt;br /&gt;
If the Holland image contained an item called Length, it would&lt;br /&gt;
be impossible to tell whether &amp;lt;tt&amp;gt;%holland:length&amp;lt;/tt&amp;gt; referred&lt;br /&gt;
to the Length item in the Holland image or the intrinsic Length&lt;br /&gt;
method applied to %holland.&lt;br /&gt;
 &lt;br /&gt;
Because of this ambiguity, intrinsic methods cannot be used against percent variables&lt;br /&gt;
without a blank between the variable name and the colon if there is an image&lt;br /&gt;
with the same name as the percent variable.&lt;br /&gt;
This is true regardless of whether or not there is an actual conflict between&lt;br /&gt;
the method name and an image item name.&lt;br /&gt;
 &lt;br /&gt;
So, using the above example, to apply the length method to&lt;br /&gt;
&amp;lt;tt&amp;gt;%holland&amp;lt;/tt&amp;gt;, you must do one of the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    %a = %holland :length&lt;br /&gt;
    %a = %holland : length&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Specifying &amp;lt;tt&amp;gt;%holland: length&amp;lt;/tt&amp;gt; would not work.&lt;br /&gt;
A space after the variable name indicates that the reference&lt;br /&gt;
is &#039;&#039;not&#039;&#039; to the image because image item references do not allow any&lt;br /&gt;
blanks between the image name, colon, and image item name.&lt;br /&gt;
 &lt;br /&gt;
You can also simply wrap the variable name in parentheses:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    %a = (%holland):length&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Of course, the best solution is to avoid using the same name for images&lt;br /&gt;
and percent variables, as this is generally somewhat confusing,&lt;br /&gt;
anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;printtext&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
===Intrinsic methods in a Print, Audit, or Trace statement===&lt;br /&gt;
The User Language Print, Audit, and Trace statements all use somewhat unusual&lt;br /&gt;
syntax.&lt;br /&gt;
While initially these statements appear to operate&lt;br /&gt;
on expressions, just like an assignment, this is not really the case.&lt;br /&gt;
For example, the following statement gets a compilation error:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    print 3*4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Because of this, one has to be careful using intrinsic methods in&lt;br /&gt;
a Print, Audit, or Trace statement. The general recommendation is to use PrinText,&lt;br /&gt;
AuditText, or TraceText, as described below. &lt;br /&gt;
&lt;br /&gt;
There are several specific syntax problems with Print, Audit, and Trace:&lt;br /&gt;
&amp;lt;ul&amp;gt; &lt;br /&gt;
&amp;lt;li&amp;gt;Because blanks are treated specially in these statements, you&lt;br /&gt;
may not put a blank before the colon in an intrinsic method invocation.&lt;br /&gt;
That is, the following is &#039;&#039;&#039;&#039;&#039;incorrect&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    print %x :length&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
But the following two statements are allowed:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    print %x:length&lt;br /&gt;
    print %x: length&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;String and literal constants are treated specially by these&lt;br /&gt;
statements, so you cannot issue methods against constants in a Print, Audit,&lt;br /&gt;
or Trace statement.&lt;br /&gt;
That is, the following are &#039;&#039;&#039;&#039;&#039;incorrect&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    print &#039;Foobar&#039;:length&lt;br /&gt;
    print 22:squareRoot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;li&amp;gt;Although you might be tempted to use parentheses to get around some of&lt;br /&gt;
these issues, leading parentheses are &#039;&#039;&#039;not&#039;&#039;&#039; allowed&lt;br /&gt;
in a Print, Audit, or Trace statement token.&lt;br /&gt;
That is, the following is &#039;&#039;&#039;&#039;&#039;incorrect&#039;&#039;&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    print (fieldname):length&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Coupled with the fact that applying intrinsic methods to fields&lt;br /&gt;
generally requires use of parentheses, this means that you &#039;&#039;&#039;cannot&#039;&#039;&#039; display&lt;br /&gt;
the result of an intrinsic method applied to a field with the Print,&lt;br /&gt;
Audit, and Trace methods.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Fortunately, &#039;&#039;Sirius Mods&#039;&#039; version 7.2, the same version that introduced intrinsic&lt;br /&gt;
methods, also introduced the &#039;&#039;&#039;PrintText&#039;&#039;&#039;, &#039;&#039;&#039;AuditText&#039;&#039;&#039;,&lt;br /&gt;
and &#039;&#039;&#039;TraceText&#039;&#039;&#039; statements ([[Targeted Text statements]]).&lt;br /&gt;
These are direct analogs of Print, Audit, and Trace, respectively, but they use&lt;br /&gt;
a more consistent syntax.&lt;br /&gt;
Specifically, the newer statements treat everything as literal text, except&lt;br /&gt;
for that which is enclosed by curly braces (&amp;lt;tt&amp;gt;{ }&amp;lt;/tt&amp;gt;),&lt;br /&gt;
which is treated as a standard User Language expression.&lt;br /&gt;
This means that the syntax used for variable parts of PrintText, AuditText,&lt;br /&gt;
and Tracetext statements is identical to the syntax allowed on the right&lt;br /&gt;
side of a variable assignment.&lt;br /&gt;
 &lt;br /&gt;
So, the following is valid:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    printText {3*4}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
And this is valid:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    printText {%x:length}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
These are valid statements:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    printText {&#039;Foobar&#039;:length}&lt;br /&gt;
    printText {22:squareRoot}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
And this is valid:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    printText {(fieldname):length}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The [[Text and Html statements|Text statement]])&lt;br /&gt;
also provides functionality comparable to the PrintText,&lt;br /&gt;
AuditText, and TraceText statements, and it is especially useful for displaying&lt;br /&gt;
multiple lines of data.&lt;br /&gt;
 &lt;br /&gt;
So it is recommended that you discontinue the use of the Print, Audit, and&lt;br /&gt;
Trace statements in favor of PrintText, AuditText, and TraceText, as of &#039;&#039;Sirius Mods&#039;&#039;&lt;br /&gt;
7.2.&lt;br /&gt;
&lt;br /&gt;
[[Category:System classes]]&lt;br /&gt;
[[Category:Overviews]]&lt;/div&gt;</summary>
		<author><name>Jeff</name></author>
	</entry>
	<entry>
		<id>https://m204wiki.rocketsoftware.com/index.php?title=Getting_started_with_OOP_for_User_Language_programmers&amp;diff=2269</id>
		<title>Getting started with OOP for User Language programmers</title>
		<link rel="alternate" type="text/html" href="https://m204wiki.rocketsoftware.com/index.php?title=Getting_started_with_OOP_for_User_Language_programmers&amp;diff=2269"/>
		<updated>2010-09-05T21:24:01Z</updated>

		<summary type="html">&lt;p&gt;Jeff: changed &amp;quot;functions are subroutines&amp;quot; to &amp;quot;functions and subroutines&amp;quot; in 1st para of &amp;quot;Object-oriented syntax&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Background==&lt;br /&gt;
So, you&#039;re a [[User Language]] programmer and you&#039;re thinking about learning object-oriented programming:&lt;br /&gt;
*Rumor has it you can be a more effective programmer if you use object-oriented techniques.&lt;br /&gt;
*You&#039;re tired of feeling inferior to object-oriented programmers because they speak a language that you don&#039;t understand but sure as heck sounds impressive.&lt;br /&gt;
*You use [[Sirius Software]] products and Sirius has announced that all new User Language functionality will used object-oriented syntax.&lt;br /&gt;
*&amp;amp;ldquo;Object-oriented&amp;amp;rdquo; looks better on your resume than &amp;amp;ldquo;User Language&amp;amp;rdquo;.&lt;br /&gt;
*You just want to learn something new.&lt;br /&gt;
Unfortunately, most User Language programmers&#039; first experience with object-oriented programming is painful and bewildering. Often it comes in the form of a VB.Net or Java class where the terminology flows freely from day one. Even worse:&lt;br /&gt;
*Classes often emphasize how one architects an object-oriented application. While this might be a logical way to build an application, it&#039;s a daunting way to learn a language &amp;amp;mdash; like trying to learn ballroom dancing before you know how to walk.&lt;br /&gt;
*Teachers (and books about object-oriented programming) are often enamored with the more sophisticated aspects of object-oriented programming languages, leaving novices in the dust as they&#039;re still struggling to digest the simpler concepts.&lt;br /&gt;
*Many object-oriented concepts are inter-related so it often requires plowing ahead without fully understanding the concepts one has already learned.&lt;br /&gt;
*There seems no way to put the concepts learned in a Java or VB.Net class to use in User Language. So, one is either forced to try to work on object-oriented programming in one&#039;s free time, or the concepts are quickly forgotten.&lt;br /&gt;
Fortunately, there &#039;&#039;&#039;is&#039;&#039;&#039; a way you can learn object-oriented programming, and apply the principles on-the-job from day one!&lt;br /&gt;
&lt;br /&gt;
One requirement for this is that one work at a site where [[Janus SOAP User Language Interface]] is available or, at least some of the other Sirius &amp;amp;ldquo;API&amp;amp;rdquo; products such as Janus Web Server or Janus Sockets.&lt;br /&gt;
&lt;br /&gt;
First, a quick word about terminology. In English-speaking, as opposed to American-speaking countries, objected-oriented is usually called object-orientated. More commonly, everyone just calls object-oriented programming &amp;amp;ldquo;O-O&amp;amp;rdquo;.   But then, you knew that.&lt;br /&gt;
&lt;br /&gt;
==Mixed case code==&lt;br /&gt;
So, let&#039;s get started. First, if you&#039;re going to do O-O programming you&#039;ve got to write your code in mixed case. No, there is no technical reason O-O code in User Language must be in mixed case but:&lt;br /&gt;
*It&#039;s easy enough to do and, even if you don&#039;t use O-O, it makes your code look more modern.&lt;br /&gt;
*The industry consensus is that descriptive, often compound words, are better for variable, function, and subroutine names than terse non-descriptive names. For example, %itemNumber is better than %ITMN. While the latter is easier to type, the former is much easier to read. USing %ITEMNUMBER, on the  other hand, clearly blunts some of that readability benefit. %itemNumber is written in what&#039;s called [http://en.wikipedia.org/wiki/CamelCase CamelCase].&lt;br /&gt;
*Sirius Software depends on CamelCase to make their function and subroutine names readable.&lt;br /&gt;
&lt;br /&gt;
Fortunately, it&#039;s easy to start using mixed case code. Simply start typing your code in mixed case. What can possibly go wrong? If you&#039;re system manager has set everything up nicely for you, nothing. But, if not, you might hot a few glitches that are easy enough to fix:&lt;br /&gt;
*If you use the 204 editor and type in mixed case code and it gets converted to upper case when you hit enter, you have two options:&lt;br /&gt;
*#Set *LOWER at command level. This is a bit of a hassle because now Model 204 commands require holding the shift key down, because mixed case Model 204 command don&#039;t work.&lt;br /&gt;
*#Set the SIREDIT user parameter to X&#039;33&#039; (only the X&#039;01&#039; bit is required, but you may as well set some others) before entering the editor. This causes Model 204 to essentially switch to *LOWER mode before entering the editor. Request that your system manager do this for everyone by setting SIREDIT X&#039;33&#039; in CCAIN. &lt;br /&gt;
&lt;br /&gt;
*If you get compilation errors when you type in mixed case UL, it means that the compiler is not running in case-independent mode. To fix this, you have three options:&lt;br /&gt;
*#Have your system manager set the X&#039;01&#039; bit in the system COMPOPT parameter. This must be done in CCAIN and is probably the best/simplest option.&lt;br /&gt;
*#Change the BEGIN or B statement at the start of the request you&#039;re working on to use mixed case, as in &#039;&#039;Begin&#039;&#039;, &#039;&#039;begin&#039;&#039;, or &#039;&#039;b&#039;&#039;.&lt;br /&gt;
*#If you can&#039;t change the start of the program, add the line &#039;&#039;Sirius Case ToUpper&#039;&#039; (the case of the words, doesn&#039;t matter) to the start of the procedure you&#039;re working on.&lt;br /&gt;
The following is an example of a mixed case User Language program that starts with a mixed case &#039;&#039;Begin&#039;&#039;:&lt;br /&gt;
  begin&lt;br /&gt;
  print &#039;Hello World!&#039;&lt;br /&gt;
  end&lt;br /&gt;
The following is an example of an &#039;&#039;Includ&#039;&#039;ed procedure that contains a &#039;&#039;Sirius Case ToUpper&#039;&#039; directive:&lt;br /&gt;
  sirius case toUpper&lt;br /&gt;
  subroutine hello&lt;br /&gt;
     print &#039;Hello World!&#039;&lt;br /&gt;
  end subroutine&lt;br /&gt;
Note that mixed case UL support is case independent so you can write UL statements in an case, and you can refer to Model 204 variables in any case. The following illustrates a little island of mixed case code in the middle of some upper case code:&lt;br /&gt;
  SUBROUTINE FOOBAR(%INPUT IS FLOAT)&lt;br /&gt;
     %MSG   IS STRING LEN 32&lt;br /&gt;
     %TOTAL IS FLOAT&lt;br /&gt;
     ...&lt;br /&gt;
     if %input gt %total then&lt;br /&gt;
        %msg = &#039;Input value too big&#039;&lt;br /&gt;
     end if&lt;br /&gt;
     ...&lt;br /&gt;
     PRINT %MSG&lt;br /&gt;
  END SUBROUTINE&lt;br /&gt;
This illustrates that you don&#039;t have to convert an entire procedure (or request) to mixed case to take advantage of mixed case UL, though, obviously, in the long-term, it&#039;s a good goal to aim for relatively consistent casing in all your code. In the short term, however, a bit of inconsistency will have to be tolerated to get to the point where most or all UL code is in mixed case. Certainly, any new procedures should be written completely in mixed case. &lt;br /&gt;
&lt;br /&gt;
As this example, illustrates, you don&#039;t have to learn anything new to enter UL in mixed case (&#039;&#039;&#039;all&#039;&#039;&#039; statements still work the same way) so there is no excuse not to start.&lt;br /&gt;
==Object-oriented syntax==&lt;br /&gt;
The most pernicious difference between O-O languages and procedural languages such as User Language (we&#039;ll just call it &#039;&#039;UL&#039;&#039; from here on) is the syntax. And the biggest syntactic difference between O-O and UL is how functions and subroutines are invoked. Let&#039;s start with functions. All UL programmers know how to invoke a function.&lt;br /&gt;
&lt;br /&gt;
First, functions are called $functions (dollar-functions) or &amp;amp;pound;functions (pound-functions) in the UK. $functions (except some of the Sirius $functions) &#039;&#039;&#039;always&#039;&#039;&#039; return a value so must either be on the right side of an assignment, input to a subroutine or other $function call, or inside some UL expression. The following example, has a $substr in all three contexts:&lt;br /&gt;
  %x = $substr(%y, 3, 10)&lt;br /&gt;
  call clever($substr(%y, %start, %len))&lt;br /&gt;
  %z = $substr(%y, %len, 1) + 10&lt;br /&gt;
As the above example illustrates, and all UL programmers know, a $function can be followed by the $function arguments (inputs) in parentheses with multiple arguments separated by commas.&lt;br /&gt;
&lt;br /&gt;
O-O functions, on the other hand, use a syntax where a function invocation consists of the thing (object, if you will) that the function is operating on specified &#039;&#039;&#039;before&#039;&#039;&#039; the function name, followed by its arguments inside parentheses. Many $functions have O-O equivalents and $substr is no exception: its O-O equivalent is called &#039;&#039;substring&#039;&#039;. The following illustrates the use of the O-O &#039;&#039;substring&#039;&#039; function by replacing &#039;&#039;$substr&#039;&#039; in the previous example with &#039;&#039;substring&#039;&#039;: &lt;br /&gt;
  %x = %y:substring(3, 10)&lt;br /&gt;
  call clever(%y:substring(%start, %len))&lt;br /&gt;
  %z = %y:substring(%len, 1) + 10&lt;br /&gt;
While this might look strange to a User Language programmer, it uses the most common O-O syntax so can honestly be called O-O programming. So, if you find any &#039;&#039;$substr&#039;&#039; call in your system and change it to use substring (moving the first argument before a :substring) you have now done some O-O coding. It&#039;s that easy!&lt;br /&gt;
&lt;br /&gt;
To further add to your bona fides as an object oriented programmer, don&#039;t call substring a function, but call it a &#039;&#039;method&#039;&#039;. In addition, don&#039;t call %y just a string, call it a &#039;&#039;string object&#039;&#039;. Now you&#039;re ready for something more advanced. Say &amp;amp;ldquo;I applied the substring method to the string object&amp;amp;rdquo;. Repeat until it feels natural to say it. Congratulations, you&#039;re well on your way to becoming an O-O programmer and, maybe even a guru. If you&#039;re curious about what you just said:&lt;br /&gt;
*Method is just a fancy word that means function or subroutine or any other called code that does something.&lt;br /&gt;
*Object is just a fancy word for a thingy.&lt;br /&gt;
Now, of course, there are many functions available other than just Substring. The functions that operate on strings are called &#039;&#039;Intrinsic String Methods&#039;&#039;. You can find a list of the methods at [[List of Intrinsic String Methods]]. There are also functions that operate on numbers. The list of these can be found at [[List of Intrinsic Float Methods]].&lt;br /&gt;
&lt;br /&gt;
Now, while congratulating yourself on your new-found skills, you might have the gnawing feeling inside that you really haven&#039;t accomplished a lot, as much as you have learned. So what have you accomplished? Is O-O syntax really better than what you&#039;re used to? At first blush, it would seem worse, as the traditional $function call is more like English, where verb (function name) precedes the object (first parameter), as opposed to the O-O syntax, where the order is reversed. For example, one would say &amp;amp;ldquo;get the substring of %y&amp;amp;rdquo; not &amp;amp;ldquo;%y get the substring&amp;amp;rdquo; so&lt;br /&gt;
  %x = $substr(%y, 2, 3)&lt;br /&gt;
&#039;&#039;&#039;seems&#039;&#039;&#039; more natural than&lt;br /&gt;
  %x = %y:substring(2, 3)&lt;br /&gt;
While this might be true, it&#039;s easy enough to get used to the second form &amp;amp;mdash; in many languages the object comes before the verb.&lt;br /&gt;
&lt;br /&gt;
In any case, the chief advantage of O-O syntax is that because the input of a function is to the left of the function, one can invoke a function and then pass the result of that function to another function by placing the second function call after the first. Similarly, a third function can be placed to the right of second to process its output. To illustrate, consider the following:&lt;br /&gt;
  %x = %y:substring(%start, %len):toUpper:unspace&lt;br /&gt;
This reads rather nicely, left to right: take &#039;&#039;%y&#039;&#039; get a substring, convert to upper case, and remove extra blanks. The traditional version doesn&#039;t read nearly as nicely:&lt;br /&gt;
  %x = $unspace($upcase($substr(%y, %start, %len)))&lt;br /&gt;
Since the processing happens in inside out order, presumably one should read this code inside out but, of course, this is very difficult. In addition, because only a colon is required as a separator character, and because no dollar-sign is required to distinguish a function from other entities, the O-O version is shorter, in spite of the fact that the function names are somewhat longer, and so, more meaningful. Perhaps more important, the O-O expression contains fewer &amp;amp;ldquo;noise&amp;amp;rdquo; characters. All of these lead to much better readability for the O-O expression. And, just as spaces can be placed around parentheses in a $function invocation to improve readability, spaces can be placed around the colon used to separate the object and function name:&lt;br /&gt;
  %x = %y : substring( %start, %len ): toUpper :unspace&lt;br /&gt;
&lt;br /&gt;
This example used inconsistent spacing just to illustrate what&#039;s allowed, not to suggest that inconsistent spacing is recommended &amp;amp;mdash; it&#039;s not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, to continue the process of becoming an object-oriented User Language programmer, you should familiarize yourself with the list of intrinsic string and float methods and try to use them wherever possible and try to use them in lieu of the $function equivalents. There is no performance penalty for doing so &amp;amp;mdash; in some cases O-O functions and $functions share the same underlying code.&lt;br /&gt;
===Named parameters===&lt;br /&gt;
The Sirius object-oriented User Language implementation has support for named parameters, parameters that can be specified by name, rather than position. While, strictly speaking, this has nothing to do with O-O programming (in fact, few O-O languages support it -- Java and VB.Net do not) named parameters are used in many Sirius methods, so it is important to understand them. To specify a value for a named parameter, simply specify the name, followed by an equals sign (&#039;&#039;=&#039;&#039;), followed by the value. For example, the Right and Left String functions have a &#039;&#039;Pad&#039;&#039; named parameter that indicates the pad character to be used if the input string is shorter than the requested length:&lt;br /&gt;
  %x = %y:right(20, pad=&#039;0&#039;)&lt;br /&gt;
In this case, the name simply makes the code clearer as without the name:&lt;br /&gt;
  %x = %y:right(20, &#039;0&#039;)&lt;br /&gt;
it&#039;s far less obvious what the second parameter means. In functions with large numbers of parameters, the named parameters can also be very useful for eliminating the need for placeholder commas, and for making the function invocations more readable. String and Float methods tend not to have a lot of parameters so named parameters are not heavily used for them, but they &#039;&#039;&#039;are&#039;&#039;&#039; used here and there, so it&#039;s important to understand them.&lt;br /&gt;
==Stringlists==&lt;br /&gt;
The object-oriented extensions to User Language are provided by Sirius Software and are only available at sites that can use $lists. Most sites that &#039;&#039;&#039;can&#039;&#039;&#039; use $lists, &#039;&#039;&#039;do&#039;&#039;&#039; use $lists because many Sirius $functions require them as input or outputs, and because they are just generally useful.&lt;br /&gt;
$lists are essentially objects because an object is a container for information that is accessed via a reference variable, and multiple reference variables can refer to the same object ($list). For example:&lt;br /&gt;
  %list     is float&lt;br /&gt;
  %list2    is float&lt;br /&gt;
   ...&lt;br /&gt;
  %list  = $listNew&lt;br /&gt;
  %list2 = %list1&lt;br /&gt;
  $listAdd(%list, &#039;Now is the winter&#039;)&lt;br /&gt;
  print $listInf(%list2, 1)&lt;br /&gt;
In this example, the &#039;&#039;Print&#039;&#039; statement would end up printing &amp;amp;ldquo;Now is the winter&amp;amp;rdquo; even though the &#039;&#039;$listAdd&#039;&#039; added the line to &#039;&#039;%list&#039;&#039;.&lt;br /&gt;
Both &#039;&#039;%list&#039;&#039; and &#039;&#039;%list2&#039;&#039; ;point to the same $list (object) and, so, it is not surprising that what is added via &#039;&#039;%list&#039;&#039; can be seen via &#039;&#039;%list2&#039;&#039;. It is clear, too, that %list and %list2 must be &#039;&#039;&#039;pointers&#039;&#039;&#039; to $list objects and cannot be the objects, themselves, since a Float value couldn&#039;t possibly hold the contents of a $list.&lt;br /&gt;
&lt;br /&gt;
So, when you were using $lists, you were using object-oriented programming capabilities even though you might not have realized it. However, you were &#039;&#039;&#039;not&#039;&#039; using object-oriented syntax to access the $list objects and so the benefits of a pure object-oriented facility were not available to you.&lt;br /&gt;
&lt;br /&gt;
The pure object-oriented equivalennt of $lists is called &#039;&#039;Stringlists&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Jeff</name></author>
	</entry>
	<entry>
		<id>https://m204wiki.rocketsoftware.com/index.php?title=BATCH2_(TCP/IP)&amp;diff=2171</id>
		<title>BATCH2 (TCP/IP)</title>
		<link rel="alternate" type="text/html" href="https://m204wiki.rocketsoftware.com/index.php?title=BATCH2_(TCP/IP)&amp;diff=2171"/>
		<updated>2010-09-01T13:10:05Z</updated>

		<summary type="html">&lt;p&gt;Jeff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;BATCH2 is the name for a program that allows a stream of Model 204 commands in a sequential file to be sent to a [[Model 204]] [[Online]] and to have the output from the Online to be saved to another sequential output file. There are basically two BATCH2 programs:&lt;br /&gt;
#A BATCH2 program written in assembler and provided by Rocket Software that uses CRAM as its transport. Because CRAM is an inter-address space transport, this BATCH2 can only work if the BATCH2 program is running on the same machine and [http://en.wikipedia.org/wiki/LPAR LPAR] as the target Online.&lt;br /&gt;
#A BATCH2 program written in C provided by [[Sirius Software]] that uses TCP/IP as its transport. Because TCP/IP allows communication between two different machines, there are no restrictions on where the BATCH2 program is relative to the target Online. This is the BATCH2 program that is the subject of this page.&lt;br /&gt;
The original TCP/IP BATCH2 was expected to be run on [http://en.wikipedia.org/wiki/Unix Unix]. As such, it originally used Unix-style command line parameters. The TCP/IP BATCH2 was then extended to support [http://en.wikipedia.org/wiki/Microsoft_Windows Microsoft Windows] and, finally, was extended to work on IBM mainframe operating systems [http://en.wikipedia.org/wiki/VM_%28operating_system%29 VM] and [http://en.wikipedia.org/wiki/MVS MVS] (now known as [http://en.wikipedia.org/wiki/Z/OS z/OS]).&lt;br /&gt;
&lt;br /&gt;
The mainframe implementations of the TCP/IP BATCH2 continued to use the Unix-style parameters. Unfortunately, because the CRAM BATCH2 used a totally different parameter list, this made it difficult to easily convert programs that used the CRAM BATCH2 to use the TCP/IP BATCH2. The ability to do this would be useful at a site that had multiple mainframe LPARs or machines &amp;amp;mdash; it can be useful to have a BATCH2 program running on one LPAR or machine communicating with a an Online on another.  Because of this, BATCH2 was modified so that there was a version that used a parameter list identical to that used by the CRAM BATCH2.&lt;br /&gt;
==Requirements==&lt;br /&gt;
For the TCP/IP BATCH2 program to comunicate with an Online, that Online must have a Janus IFDIAL port defined.&lt;br /&gt;
For this to be possible, the Online must be linked with the [[Sirius Mods]] and must be authorized for the Janus TCP/IP Base product.&lt;br /&gt;
If an Online is authorized for Janus TCP/IP Base, an IFDIAL port can be defined with the JANUS DEFINE command, as in:&lt;br /&gt;
  JANUS DEFINE IFDIAL 2231 IFDIAL 5 IBSIZE 4096 OBSIZE 8192 MAXREC 256&lt;br /&gt;
This defines a port that can be accessed via BATCH2 at port number 2231 on all IP addresses (it can be more than one if the host is [http://en.wikipedia.org/wiki/Multihoming multi-homed]) on the Onine&#039;s host machine.&lt;br /&gt;
&lt;br /&gt;
The IBM C run-time libraries must also be available on the host where the z/OS or CMS BATCH2 program is running. Since these are now part of the standard z/OS and CMS distribution, this should only be a problem insofar as locating the libraries.&lt;br /&gt;
&lt;br /&gt;
==CRAM BATCH2 compatibility==&lt;br /&gt;
If one would like to migrate from an environment where all BATCH2 jobs run on the same machine and LPAR as the target Onlines to an environment where the machine or LPAR running the BATCH2 and Online jobs could be mixed and matched, it would be ideal if the change could be made by simply replacing the CRAM BATCH2 load module with the TCP/IP module without any changes to the BATCH2 JCL.&lt;br /&gt;
&lt;br /&gt;
But providing a TCP/IP BATCH2 that is plug compatible with the CRAM BATCH2 presents some special challenges. Most importantly, the target Online for a CRAM BATCH2 program is indicated by the first comma-delimited parameter. This parameter is an 8-byte or shorter CRAM channel name. But the TCP/IP BATCH2 requires a host name (which is often 16 bytes or longer) or IP address, and a port number. So, to provide CRAM BATCH2 compatibility, the mainframe TCP/IP BATCH2 must be linked with an assembler program that maps CRAM channel names to host names and port numbers.&lt;br /&gt;
&lt;br /&gt;
This program is called BATCH2CH (for BATCH2 CHannel) and consists of pairs of null-terminated CRAM channel names, and host names or IP addresses and port numbers. The host name and port number must be separated by the space character. For example:&lt;br /&gt;
          ENTRY BATCH2CH&lt;br /&gt;
 BATCH2CH RMODE ANY&lt;br /&gt;
 BATCH2CH CSECT&lt;br /&gt;
          DC    C&#039;IOCALE&#039;,AL1(0)&lt;br /&gt;
          DC    C&#039;sirius-software.com 2231&#039;,AL1(0)&lt;br /&gt;
          DC    C&#039;IOALE&#039;,AL1(0)&lt;br /&gt;
          DC    C&#039;sirijes2.sirius-software.com 2231&#039;,AL1(0)&lt;br /&gt;
          DC    AL1(0)&lt;br /&gt;
          END&lt;br /&gt;
In this example, CRAM channel IOCALE is mapped to host &#039;&#039;sirius-software.com&#039;&#039;, port number 2231, and CRAM channel IOALE is mapped to host &#039;&#039;sirijes2.sirius-software.com&#039;&#039;, port 2231. The list is terminated with a single null (AL1(0)) after the last host name and port number. This allows the TCP/IP BATCH2 to be invoked with one of the CRAM channel names in BATCH2CH:&lt;br /&gt;
 //BATCH2   EXEC PGM=BATCH2,REGION=4096K,     &lt;br /&gt;
 //             PARM=&#039;IOCALE&#039;                 &lt;br /&gt;
In the above example, if the BATCH2 program was linked with the (assembled) preceding BATCH2CH, it would try to connect to host &#039;&#039;sirius-software.com&#039;&#039; port 2231.&lt;br /&gt;
==Program parameters==&lt;br /&gt;
To maintain compatibility with the CRAM BATCH, the TCP/IP BATCH2 for z/OS now supports a parameter list identical to that used by the CRAM BATCH2. The format of the parameter list is:&lt;br /&gt;
  [channel][,[OMC={X&#039;xx&#039; | num}][,URCTYPE={N | O | B}]]&lt;br /&gt;
where&lt;br /&gt;
;channel : Is the name of the CRAM channel name mapped in IFDIALCH.&lt;br /&gt;
; OMC value : Is either the hexadecimal or decimal (value must be less than 256) mask to be use to indicate special processing for certain server messages. The default value of OMC is zero (as it is for the CRAM BATCH2) which means that there is no special processing for server messages. The OMC value bit&#039;s indicate which messages are to be specially processed:&lt;br /&gt;
:;X&#039;04&#039; : Informational messages are to be suppressed from the output stream.&lt;br /&gt;
:;X&#039;08&#039; : $read prompts are to be suppressed from the output stream.&lt;br /&gt;
:;X&#039;10&#039; : Password prompts are to be suppressed from the output stream.&lt;br /&gt;
:;X&#039;20&#039; : A user restart should immediately terminate the BATCH2 job. When this happens, the return code from BATCH2 is set to 300.&lt;br /&gt;
:;X&#039;40&#039; : New page indicators are to be ignored.&lt;br /&gt;
:;X&#039;80&#039; : Error messages are to be suppressed from the output stream.&lt;br /&gt;
;URCTYPE value : Indicates whether errors in processing the BATCH2 job stream in the Online are to be reflected in the BATCH2 return code and, if so, which error code is to be used. The default value value of URCTYPE is N (as it is for the CRAM BATCH2) which means that errors in processing the BATCH2 job stream in the Online are not reflected in the BATCH2 return code. Regardless of the setting of URCTYPE, communications errors between BATCH2 and the Online will result in a variety of BATCH2 return codes, depending on the nature of the error. Return codes from the Online above 99 are converted to BATCH2 return code of 99 to prevent confusion with communication error return code. This is almost never a problem because, generally, even the most severe errors don&#039;t set return codes greater than 16. The values of the URCTYPE parameter are:&lt;br /&gt;
:;N : Don&#039;t reflect any errors in the job stream in the BATCH2 return code.&lt;br /&gt;
:;B : Set the BATCH2 return code to the value that a BATCH204 job running the identical job stream would return.&lt;br /&gt;
:;O : Set the BATCH2 return code to the value set for Online jobs. Generally, the return code reflected for URCTYPE=O will be less than that for URCTYPE=B &amp;amp;mdash; non-severe errors will often return 4 for URCTYPE=B and 0 for URCTYPE=O.&lt;br /&gt;
The following is an example of an EXEC card that invokes BATCH2 for channel IOALE, requesting that a user restart terminate the run (OMC=X&#039;20&#039;), and that batch return codes are to be used to set the BATCH2 return code:&lt;br /&gt;
 //BATCH2   EXEC PGM=BATCH2,REGION=4096K,&lt;br /&gt;
 //             PARM=&#039;IOALE,OMC=X&#039;&#039;20&#039;&#039;,URCTYPE=B&#039;&lt;br /&gt;
The single quotes in the OMC values must be doubled because they occur inside single quotes for the job card.&lt;br /&gt;
==Trusted login==&lt;br /&gt;
Another compatibility issue with the CRAM BATCH2 is that CRAM BATCH2 job stream is capable of doing a &amp;amp;ldquo;trusted login&amp;amp;rdquo; in the server Online. A trusted login logs on to the Online with the same userid as the userid under which BATCH2 is running. This requires that the same userid be able to run batch jobs and to log into Model 204.&lt;br /&gt;
This is typically not much of a problem at sites where an external authorizer such as [http://en.wikipedia.org/wiki/RACF RACF], [http://en.wikipedia.org/wiki/ACF2 ACF2], and Top Secret (by [http://en.wikipedia.org/wiki/Computer_Associates Computer Associates]) because userids for both JES and Model 204 are managed from the same security server.&lt;br /&gt;
&lt;br /&gt;
A trusted login is usually indicated by a &amp;amp;ldquo;naked&amp;amp;rdquo; &#039;&#039;LOGIN&#039;&#039;, that is a &#039;&#039;LOGIN&#039;&#039; command with no userid (or anything else) specified:&lt;br /&gt;
  LOGON&lt;br /&gt;
  OPEN FILE ALEXPROC&lt;br /&gt;
  V&lt;br /&gt;
  ...&lt;br /&gt;
With CRAM BATCH2 it is relatively easy to securely validate the userid under which the BATCH2 program is running because BATCH2 and Model 204 are running on the same machine or LPAR and so cross-memory services can be used to retrieve and validate the userid.&lt;br /&gt;
For the TCP/IP BATCH2 the picture is somewhat more complicated. While the TCP/IP BATCH2 always passes the userid under which it is running to the Model 204 server, there is no particular reason for Model 204 to trust that the BATCH2 job should be allowed to run as that userid. This is because that BATCH2 might be running on a different machine from the Online and so could, in theory, be a BATCH2 program or BATCH impostor that is being used by someone trying to breach security.&lt;br /&gt;
&lt;br /&gt;
So, to add a bit of control to TCP/IP BATCH2 trusted login, the userid passed by BATCH2 will only be used for a trusted login if a &#039;&#039;TRUST&#039;&#039; clause was specified for the target IFDIAL port, and that &#039;&#039;TRUST&#039;&#039; clause indicated an IP address or subnet that matches the BATCH client&#039;s IP address. The &#039;&#039;TRUST&#039;&#039; keyword on a &#039;&#039;JANUS DEFINE&#039;&#039; for an IFDIAL port must be followed by one or more IP addresses or subnets, separated by an &#039;&#039;AND&#039;&#039; keyword. Up to 16 IP addresses of subnets are allowed in a &#039;&#039;TRUST&#039;&#039; clause.&lt;br /&gt;
&lt;br /&gt;
An IP address must be specified using standard [http://en.wikipedia.org/wiki/Dotted_decimal_notation dotted decimal notation] as in, for example, 198.242.244.47 (the IP address of Sirius Software&#039;s corporate web server).&lt;br /&gt;
&lt;br /&gt;
A subnet can be specified either with an IP address followed by a [http://en.wikipedia.org/wiki/Subnetwork_mask subnet mask], both using dotted decimal notation and separated by a / character, or an IP address followed by a number of leading bits in the subnet part of the address, separated by a dash.&lt;br /&gt;
So 198.242.244.0/255.255.255.0 and 198.242.244.0-24 both describe the same class C subnetwork that just happens to be Sirius Software&#039;s subnet.&lt;br /&gt;
&lt;br /&gt;
The following is an example of a &#039;&#039;TRUST&#039;&#039; clause in a &#039;&#039;JANUS DEFINE&#039;&#039; for an IFDIAL port:&lt;br /&gt;
  JANUS DEFINE IFDIAL 2231 IFDIAL 5 IBSIZE 4096 OBSIZE 8192 MAXREC 256 -&lt;br /&gt;
        TRUST 198.242.244.0-24 AND 208.80.152.2&lt;br /&gt;
Generally, a TRUST list should only include specific IP addresses (as opposed to subnets) and should be limited to IP address for hosts that:&lt;br /&gt;
#Are themselves secure&lt;br /&gt;
#Limit outgoing access to the IFDIAL port to an authorized BATCH2 progam.&lt;/div&gt;</summary>
		<author><name>Jeff</name></author>
	</entry>
</feed>