Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

[r9260]: docs / branches / 4.1 / trunk / rexxref / dire.xml Maximize Restore History

Download this file

dire.xml    902 lines (843 with data), 43.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
<!--#########################################################################
#
# Description: Open Object Rexx: Reference SGML file.
#
# Copyright (c) 2005-2009, Rexx Language Association. All rights reserved.
# Portions Copyright (c) 2004, IBM Corporation. All rights reserved.
#
# This program and the accompanying materials are made available under
# the terms of the Common Public License v1.0 which accompanies this
# distribution. A copy is also available at the following address:
# http://www.oorexx.org/license.html
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the distribution.
#
# Neither the name of Rexx Language Association nor the names
# of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Author(s):
# W. David Ashley <dashley@us.ibm.com>
#
#########################################################################
-->
<chapter id="dire"><title>Directives</title>
<para>A Rexx program contains one or more executable code units.
<emphasis role="italic">Directive instructions</emphasis> separate these executable units. A
directive begins
with a double colon (::) and is a nonexecutable instruction. For example,
it cannot appear in a string for the INTERPRET instruction to be interpreted.
The first directive instruction in a program marks the end of the main executable
section of the program.</para>
<para>For a program containing directives, all directives are processed first
to set up the program's classes, methods, and routines. Then any program code
in the main code unit (preceding the first directive) is processed. This code
can use any classes, methods, and routines that the directives established.</para>
<section id="attrd"><title>::ATTRIBUTE</title>
<indexterm><primary>:: ATTRIBUTE directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::ATTRIBUTE</secondary></indexterm>
<indexterm><primary>attribute</primary>
<secondary>creation</secondary></indexterm>
<indexterm><primary>GET subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>SET subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>CLASS subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>PRIVATE subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>PUBLIC subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>GUARDED subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>UNGUARDED subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>PROTECTED subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<indexterm><primary>UNPROTECTED subkeyword</primary>
<secondary>in an ATTRIBUTE directive</secondary></indexterm>
<para>The ::ATTRIBUTE directive creates attribute methods and defines the
method properties.</para>
<programlisting>
<![CDATA[
>>-::ATTRIBUTE--name--+-----+-------+-------+------------------------->
+-GET-+ +-CLASS-+
+-SET-+
+-PUBLIC--+ +-GUARDED---+ +-UNPROTECTED-+
>--+---------+--+-----------+--+-------------+------------------->
+-PRIVATE-+ +-UNGUARDED-+ +-PROTECTED---+
>--+---------------+---;-----------------------------------------><
+-EXTERNAL-spec-+
]]>
</programlisting>
<para>The ::ATTRIBUTE directive creates accessor methods for object instance
variables. An accessor method allows an object instance variable to be
retrieved or assigned a value. ::ATTRIBUTE can create an attribute getter
method, a setter method, or the getter/setter pair.</para>
<para>The <emphasis role="italic">name</emphasis> is a literal string or
a symbol that is taken as a constant. The <emphasis role="italic">name</emphasis> must also be
a valid Rexx variable name. The ::ATTRIBUTE directive creates methods
in the class specified in the most recent ::CLASS directive. If no ::CLASS
directive precedes an ::ATTRIBUTE directive, the attribute methods are not
associated with a class but are accessible to the main (executable) part of a
program through the .METHODS built-in object. Only one ::ATTRIBUTE directive can
appear for any method name not associated with a class. See
<link linkend="methe">.METHODS</link> for more details.</para>
<para>If you do not specify either SET or GET, ::ATTRIBUTE will create two attribute methods with the
names <emphasis role="italic">name</emphasis> and <emphasis role="italic">name=</emphasis>.
These are the methods for getting and setting an attribute. These generated methods are
equivalent to the following code sequences: </para>
<programlisting>
::method "NAME=" /* attribute set method */
expose name /* establish direct access to object variable (attribute) */
use arg name /* retrieve argument and assign it to the object variable */
::method name /* attribute get method */
expose name /* establish direct access to object variable (attribute) */
return name /* return object&apos;s current value */
</programlisting>
<para>Both methods will be created with the same method properties (for example, PRIVATE, GUARDED, etc.).
If GET or SET are not specified, the pair of methods will be automatically
generated. In that case, there is no method code body following the directive,
so another directive (or the end of the program) must follow the
::ATTRIBUTE directive.
</para>
<para>If GET or SET is specified, only the single get or set attribute method is generated.
Specifying separate
GET or SET ::ATTRIBUTE directives allows the methods to be created with different properties.
For example, the
sequence:</para>
<programlisting>
::attribute name get
::attribute name set private
</programlisting>
<para>will create a NAME method with PUBLIC access and a NAME= method with PRIVATE access.</para>
<para>The GET and SET options may also be used to override the default method body generated for the attribute. This
is frequently used so the SET attribute method can perform new value validation.</para>
<programlisting>
::attribute size get
::attribute size set
expose size /* establish direct access to object variable (attribute) */
use arg value /* retrieve argument */
if datatype(value, "Whole") = .false | value &lt; 0 then
raise syntax 93.906 array ("size", value)
size=value
</programlisting>
<para>If you specify the CLASS option, the created methods are class
methods. See <link linkend="provide">Objects and Classes</link>. The attribute methods are
associated with the class specified on the most recent ::CLASS directive. The
::ATTRIBUTE must be preceded by a ::CLASS directive if CLASS is
specified.</para>
<para>If the EXTERNAL option is specified, then <emphasis role="italic">spec</emphasis>
identifies a method in an external native library that will be invoked as the
named method. The
<emphasis role="italic">spec</emphasis> is a literal string containing a series
of whitespace delimited tokens defining the external method. The first token
must be the word LIBRARY, which indicates the method resides in a native library
of the type allowed on a ::REQUIRES directive. The second token must identify
the name of the external library. The external library is located using
platform-specific mechanisms for loading libraries. For Unix-based systems, the
library name is case-sensitive. The third token is optional and specifies the
name of the method within the library package. If not specified, the ::METHOD
name is used. The target package method name is case insensitive.</para>
<para>If the SET or GET option is not specified with the EXTERNAL option, then
two method objects need to be created. The target method name is appended to
the string "GET" to derive the name of the getter attribute method. To generate
the setter attribute method, the name is appended to the string "SET".
If GET or SET is specified and the method name is not specified within
<emphasis role="italic">spec</emphasis>, then the target library method name
is generated by concatenating <emphasis role="italic">name</emphasis>
with "GET" or "SET" as appropriate. If the method name is specified in
<emphasis role="italic">spec</emphasis> and GET or SET is specified, the spec
name will be used unchanged.
</para>
<para><emphasis role="bold">Example:</emphasis></para>
<indexterm><primary>examples</primary>
<secondary>::ATTRIBUTE directive</secondary>
<tertiary>EXTERNAL option</tertiary></indexterm>
<programlisting>
-- maps "NAME" method to "GETNAME and
-- "NAME=" to "SETNAME"
::ATTRIBUTE name EXTERNAL "LIBRARY mylib"
-- maps "ADDRESS" method to "GETADDRESS"
::ATTRIBUTE address GET EXTERNAL "LIBRARY mylib"
-- maps "ADDRESS=" method to "setHomeAddress"
::ATTRIBUTE address SET EXTERNAL "LIBRARY mylib setHomeAddress"
</programlisting>
<para><emphasis role="bold">Notes:</emphasis></para>
<orderedlist>
<listitem><para>You can specify all options in any order.
</para></listitem>
<listitem><para>If you specify the PRIVATE option, the created methods are
private methods. Private methods have restricted access rules on how they can
be invoked.
See <link linkend="pubpri">Public versus Private Methods</link>
for details of how private methods can be used.
If you omit the PRIVATE option or specify PUBLIC, the method is a public method
that any sender can activate.
</para></listitem>
<listitem><para>If you
<indexterm><primary>UNGUARDED option of ::ATTRIBUTE</primary></indexterm>
specify the UNGUARDED option, the methods can be called while other methods are
active on the same object. If you do not specify UNGUARDED, the method requires
exclusive use of the object variable pool; it can run only if no other method
that requires exclusive use of the object variable pool is active on the same
object.</para></listitem>
<listitem><para>If you specify the PROTECTED option, the method methods are
protected methods. (See
<link linkend="secman">The Security Manager</link> for more information.)
If you omit the PROTECTED option or specify UNPROTECTED, the methods are not
protected.
</para></listitem>
<listitem><para>It is an error to specify ::ATTRIBUTE more than once within a
class definition that creates a duplicate get or set method.
</para></listitem>
</orderedlist>
</section>
<section id="clasdi"><title>::CLASS</title>
<indexterm><primary>::CLASS directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::CLASS</secondary></indexterm>
<indexterm><primary>METACLASS subkeyword</primary>
<secondary>in a CLASS directive</secondary></indexterm>
<indexterm><primary>SUBCLASS subkeyword</primary>
<secondary>in a CLASS directive</secondary></indexterm>
<indexterm><primary>MIXINCLASS subkeyword</primary>
<secondary>in a CLASS directive</secondary></indexterm>
<indexterm><primary>PUBLIC subkeyword</primary>
<secondary>in a CLASS directive</secondary></indexterm>
<indexterm><primary>PRIVATE subkeyword</primary>
<secondary>in a CLASS directive</secondary></indexterm>
<indexterm><primary>INHERIT subkeyword</primary>
<secondary>in a CLASS directive</secondary></indexterm>
<para>The ::CLASS directive causes the interpreter to create a Rexx class.</para>
<programlisting>
<![CDATA[
>>-::CLASS--classname--+----------------------+------------------->
+-METACLASS--metaclass-+
.-SUBCLASS--Object---. +-PRIVATE-+
>--+--------------------+--+---------+--+-------------------+--;--><
+-MIXINCLASS--mclass-+ +-PUBLIC--+ +-INHERIT--iclasses-+
+-SUBCLASS--sclass---+
]]>
</programlisting>
<para>The ::CLASS directive creates a Rexx class named
<emphasis role="italic">classname</emphasis>. The
<emphasis role="italic">classname</emphasis>
is a literal string or symbol that is taken as a constant.
The created class is available to programs through the Rexx environment symbol
.<emphasis role="italic">classname</emphasis>. The
<emphasis role="italic">classname</emphasis> acquires all methods defined by
subsequent ::METHOD directives until the end of the program or another ::CLASS
directive is found. Only null clauses (comments or blank lines) can appear
between a ::CLASS directive and any following directive instruction or the
end of the program. Only one ::CLASS directive can appear for
<emphasis role="italic">classname</emphasis> in a program.</para>
<para>If you specify the METACLASS option, the instance methods of the
<emphasis role="italic">metaclass</emphasis> class become class methods of the
<emphasis role="italic">classname</emphasis> class.
(See <link linkend="provide">Objects and Classes</link> .) The
<emphasis role="italic">metaclass</emphasis> and
<emphasis role="italic">classname</emphasis> are literal
strings or symbols that are taken as constants. In the search order for methods,
the metaclass methods precede inherited class methods and follow any class
methods defined by ::METHOD directives with the CLASS option.</para>
<para>If you specify the PUBLIC option, the class is visible beyond its containing
Rexx program to any other program that references this program with a ::REQUIRES
directive. (See <link linkend="requ">::REQUIRES</link>.) If you do not
specify the PUBLIC option,
the class is visible only within its containing Rexx program. All public classes
defined within a program are used before PUBLIC classes created with the same
name.</para>
<para>If you specify the SUBCLASS option, the class becomes a subclass of the
class <emphasis role="italic">sclass</emphasis> for inheritance of instance and
class methods. The <emphasis role="italic">sclass</emphasis>
is a literal string or symbol that is taken as a constant.</para>
<para>If you specify the MIXINCLASS option, the class becomes a subclass of the
class <emphasis role="italic">mclass</emphasis>
for inheritance of instance and class methods. You can
add the new class instance and class methods to existing classes by using
the INHERIT option on a ::CLASS directive or by sending an INHERIT message
to an existing class. If you specify neither the SUBCLASS nor the MIXINCLASS
option, the class becomes a non-mixin subclass of the Object class.</para>
<para>If you specify the INHERIT option, the class inherits instance methods
and class methods from the classes <emphasis role="italic">iclasses</emphasis>
in their order of appearance
(leftmost first). This is equivalent to sending a series of INHERIT messages
to the class object, with each INHERIT message (except the first) specifying
the preceding class in <emphasis role="italic">iclasses</emphasis>
as the <emphasis role="italic">classpos</emphasis> argument.
(See <link linkend="mthClassInherit">INHERIT</link> .) As with the INHERIT message,
each of the classes in <emphasis role="italic">iclasses</emphasis>
must be a mixin class. The <emphasis role="italic">iclasses</emphasis>
is a whitespace-separated list of literal strings or symbols that are taken as
constants. If you omit the INHERIT option, the class inherits only from
<emphasis role="italic">sclass</emphasis>.</para>
<para><emphasis role="bold">Example:</emphasis></para>
<indexterm><primary>examples</primary>
<secondary>::CLASS directive</secondary></indexterm>
<programlisting>
::class rectangle
::method area /* defined for the RECTANGLE class */
expose width height
return width*height
::class triangle
::method area /* defined for the TRIANGLE class */
expose width height
return width*height/2
</programlisting>
<para>The ::CLASS directives in a program are processed in the order in which
they appear. If a ::CLASS directive has a dependency on ::CLASS directives
that appear later in the program, processing of the directive is deferred
until all of the class's dependencies have been processed.</para>
<para><emphasis role="bold">Example:</emphasis></para>
<programlisting>
::class savings subclass account /* requires the ACCOUNT class */
::method type
return "a Savings Account"
::class account
::method type
return "an Account"
</programlisting>
<para>The Savings class in the preceding example is not created until the Account
class that appears later in the program has been created. </para>
<para><emphasis role="bold">Notes:</emphasis></para>
<orderedlist>
<listitem><para>You can specify the options METACLASS, MIXINCLASS, SUBCLASS, and
PUBLIC in any order. </para></listitem>
<listitem><para>If you specify INHERIT, it must be the last option.</para></listitem>
</orderedlist>
</section>
<section id="constantd"><title>::CONSTANT</title>
<indexterm><primary>::CONSTANT directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::CONSTANT</secondary></indexterm>
<indexterm><primary>attribute</primary>
<secondary>creation</secondary></indexterm>
<para>The ::CONSTANT directive creates methods that return constant
values for a class and its instances.</para>
<programlisting>
<![CDATA[
>>-::CONSTANT--name--value-------------------------------------------><
]]>
</programlisting>
<para>A ::CONSTANT directive defines a method that returns a constant value.
This is useful for creating named constants associated with a class.
</para>
<para>The <emphasis role="italic">name</emphasis> is a literal string or
a symbol that is taken as a constant. A method of the given name is created as
both an instance method and a class method of the most recent ::CLASS directive.
A ::CLASS directive is not required before a ::CONSTANT directive. If no ::CLASS
directive precedes ::CONSTANT, a single constant method method is created that
is not associated with a class but is accessible to the main (executable) part
of a program through the .METHODS built-in object. Only one ::CONSTANT directive
can appear for any method name not associated with a class. See
<link linkend="methe">.METHODS</link> for more details.</para>
<para>The methods created by a ::CONSTANT directive are UNGUARDED and will have
a return result that is specified by
<emphasis role="italic">value</emphasis>. The constant value must be a single
literal string or symbol that is taken as a constant. Also permitted is the
single character "-" or "+" followed by a literal string or symbol that is a
valid number. Here are some examples of valid constants:</para>
<programlisting>
::class MathConstants public
::constant pi 3.1415926
::constant author "Isaac Asimov"
::constant absolute_zero -273.15
</programlisting>
<para>A ::CONSTANT directive is a shorthand syntax for creating constants
associated with a class. The created name constant can be accessed using either
the class object or an instance of the class itself. For example:</para>
<programlisting>
say "Pi is" .MathConstants~pi -- displays "Pi is 3.1415926"
instance = .MathConstants~new
say "Pi is" instance~pi -- also displays "Pi is 3.1415926"
::class MathConstants public
::constant pi 3.1415926
</programlisting>
</section>
<section id="methd"><title>::METHOD</title>
<indexterm><primary>:: METHOD directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::METHOD</secondary></indexterm>
<indexterm><primary>method</primary>
<secondary>creation</secondary></indexterm>
<indexterm><primary>CLASS subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>ATTRIBUTE subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>PRIVATE subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>PUBLIC subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>GUARDED subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>UNGUARDED subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>PROTECTED subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<indexterm><primary>UNPROTECTED subkeyword</primary>
<secondary>in a METHOD directive</secondary></indexterm>
<para>The ::METHOD directive creates a method object and defines the method
attributes.</para>
<programlisting>
<![CDATA[
>>-::METHOD--methodname--+-------+--+-----------+--+----------+--->
+-CLASS-+ +-ATTRIBUTE-+ +-ABSTRACT-+
+-PUBLIC--+ +-GUARDED---+ +-UNPROTECTED-+
>--+---------+--+-----------+--+-------------+------------------->
+-PRIVATE-+ +-UNGUARDED-+ +-PROTECTED---+
>--+---------------+---;-----------------------------------------><
+-EXTERNAL-spec-+
]]>
</programlisting>
<para>A ::METHOD directive creates method objects that may be associated with a
class instance. The created method may be from Rexx code, mapped to method in
an external native library, or automatically generated. The type of method is
determined by the combination of options specified.</para>
<para>The <emphasis role="italic">methodname</emphasis> is a literal string or
a symbol that is taken as a constant. The method is defined as
<emphasis role="italic">methodname</emphasis> in the class specified
in the most recent ::CLASS directive. Only one ::METHOD directive can appear
for any <emphasis role="italic">methodname</emphasis> in a class.</para>
<para>A ::CLASS directive is not required before a ::METHOD directive. If no
::CLASS directive precedes ::METHOD, the method is not associated with a class
but is accessible to the main (executable) part of a program through the .METHODS
built-in object. Only one ::METHOD directive can appear for any method name
not associated with a class. See
<link linkend="methe">.METHODS</link> for more details.</para>
<para>If you specify the CLASS option, the method is a class
method. See <link linkend="provide">Objects and Classes</link>. The method is
associated with the class specified on the most recent ::CLASS directive. The
::METHOD directive must follow a ::CLASS directive when the CLASS option is
used.
</para>
<para>If ABSTRACT, ATTRIBUTE, or EXTERNAL is not specified, the ::METHOD
directive starts a section of method code which is ended by another directive or
the end of the program. The ::METHOD is not included in the source of the
created METHOD object.
</para>
<para><emphasis role="bold">Example:</emphasis></para>
<programlisting>
r = .rectangle~new(20,10)
say "Area is" r~area /* Produces "Area is 200" */
::class rectangle
::method area /* defined for the RECTANGLE class */
expose width height
return width*height
::method init
expose width height
use arg width, height
::method perimeter
expose width height
return (width+height)*2
</programlisting>
<para>If you specify the ATTRIBUTE option, method variable accessor methods are
created. In addition to generating a method named
<emphasis role="italic">methodname</emphasis>, another method named
<emphasis role="italic">methodname=</emphasis> is created. The first method
returns the value of object instance variable that matches the method name.
The second method assigns a new value to the object instance variable.</para>
<para>For example, the directive </para>
<indexterm><primary>examples</primary>
<secondary>::METHOD directive</secondary></indexterm>
<programlisting>
::method name attribute
</programlisting>
<para>creates two methods, NAME and NAME=. The NAME and NAME= methods are
equivalent to the following code sequences: </para>
<programlisting>
::method "NAME="
expose name
use arg name
::method name
expose name
return name
</programlisting>
<para>If you specify the ABSTRACT option, the method creates an ABSTRACT method placeholder.
ABSTRACT methods define a method that an implementing subclass is expected to provide a concrete
implementation for. Any attempt to invoke an ABSTRACT method directly will raise a SYNTAX condition.
</para>
<para>If the EXTERNAL option is specified, then <emphasis role="italic">spec</emphasis>
identifies a method in an external native library that will be invoked as the
named method. The
<emphasis role="italic">spec</emphasis> is a literal string containing a series
of whitespace delimited tokens defining the external method. The first token
must be the word LIBRARY, which indicates the method resides in a native library
of the type allowed on a ::REQUIRES directive. The second token must identify
the name of the external library. The external library is located using
platform-specific mechanisms for loading libraries. For Unix-based systems, the
library name is case-sensitive. The third token is optional and specifies the
name of the method within the library package. If not specified, the ::METHOD
name is used. The target package method name is case insensitive.</para>
<para><emphasis role="bold">Example:</emphasis></para>
<indexterm><primary>examples</primary>
<secondary>::METHOD directive</secondary>
<tertiary>EXTERNAL option</tertiary></indexterm>
<programlisting>
-- creates method INIT from method RegExp_Init
-- in library rxregexp
::METHOD INIT EXTERNAL "LIBRARY rxregexp RegExp_Init"
-- creates method INIT from method POS
-- in library rxregexp
::METHOD POS EXTERNAL "LIBRARY rxregexp"
</programlisting>
<para>If the ATTRIBUTE option is specified with the EXTERNAL option, then two
method objects need to be created. The target method name is appended to the
string "GET" to derive the name of the getter attribute method. To generate the
setter attribute method, the name is appended to the string "SET".</para>
<para><emphasis role="bold">Example:</emphasis></para>
<programlisting>
-- maps "NAME" method to "GETNAME and
-- "NAME=" to "SETNAME"
::METHOD name ATTRIBUTE EXTERNAL "LIBRARY mylib"
-- maps "ADDRESS" method to "GETMyAddress and
-- "ADDRESS=" to "SETMyAddress"
::METHOD address ATTRIBUTE EXTERNAL "LIBRARY mylib MyAddress"
</programlisting>
<para><emphasis role="bold">Notes:</emphasis></para>
<orderedlist>
<listitem><para>You can specify all options in any order.
</para></listitem>
<listitem><para>If you specify the PRIVATE option, the created methods are
private methods. Private methods have restricted access rules on how they can
be invoked.
See <link linkend="pubpri">Public versus Private Methods</link>
for details of how private methods can be used.
If you omit the PRIVATE option or specify PUBLIC, the method is a public method
that any sender can activate.
</para></listitem>
<listitem><para>If you
<indexterm><primary>UNGUARDED option of ::METHOD</primary></indexterm> specify
the UNGUARDED option, the method can be called while other methods are active on
the same object. If you do not specify UNGUARDED, the method requires exclusive
use of the object variable pool; it can run only if no other method that
requires exclusive use of the object variable pool is active on the same
object.</para></listitem>
<listitem><para>If you specify the PROTECTED option, the method is a protected
method. (See <link linkend="secman">The Security Manager</link> for more information.)
If you omit the PROTECTED option or specify UNPROTECTED, the method is
not protected.</para></listitem>
<listitem><para>If you specify ATTRIBUTE, ABSTRACT, or EXTERNAL, another
directive (or the end of the program) must follow the ::METHOD directive.
</para></listitem>
<listitem><para>It is an error to specify ::METHOD more than once within the same
class and use the same <emphasis role="italic">methodname</emphasis>.
</para></listitem>
</orderedlist>
</section>
<section id="optionsd"><title>::OPTIONS</title>
<indexterm><primary>::OPTIONS directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::OPTIONS</secondary></indexterm>
<para>The ::OPTIONS directive defines default values for numeric and trace
settings for all Rexx code contained within a package.
</para>
<programlisting>
<![CDATA[
>>-::OPTIONS--+---------------+--+-----------+--+-----------+---->
+-DIGITS-digits-+ +-FORM-form-+ +-FUZZ-fuzz-+
>------------+-------------+------------------------------------><
+-TRACE-trace-+
]]>
</programlisting>
<para>Any of the options may be specified on a single ::OPTIONS directive in any
order. If an option is specified more than once, the last specified value
will the be one used. If more than one ::OPTIONS directive appears in a source
file, the options are processed in the order they appear and the effect is
accumulative. If a given option type is specified on more than directive, the
last specified will be the value used.
</para>
<para>The specified options will override the normal default settings for all Rexx
code contained in the source file. For example, </para>
<programlisting>
::OPTIONS DIGITS 20
</programlisting>
<para>would direct that all method and routine code defined in this source package
execute with an initial <link linkend="keyNumeric">NUMERIC DIGITS</link> setting of
20 digits. The ::OPTIONS directive controls only the initial setting. A method
or routine may change the current setting with the NUMERIC DIGITS instruction as normal.
The values specified with ::OPTIONS only apply to code that appears in the same source file.
It does not apply to code in other source files that may reference or use this code.
For example, a subclass of a class defined in this source package will not inherit the
::OPTIONS settings if the subclass code is located in a different source package.
</para>
<para>The following options may be specified on an ::OPTIONS directive:</para>
<informaltable frame="none" colsep="0" rowsep="0" pgwide="1">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*">
<colspec colnum="2" colwidth="5*">
<tbody>
<row><entry>DIGITS
<indexterm><primary>::OPTIONS directive</primary>
<secondary>DIGITS option</secondary></indexterm>
</entry>
<entry>
<para>controls the precision to which arithmetic operations and
built-in functions are evaluated.
The value <emphasis role="italic">digits</emphasis> must be a symbol or string
that is a valid positive whole number value and must be larger than the
current FUZZ ::OPTIONS setting.
The package value can be retrieved using the Package class
<link linkend="mthPackageDigits">digits</link> method.
</para>
<para>There is no limit to the value for DIGITS
(except the amount of storage available), but high precisions are likely to
require a great amount of processing time. It is recommended that you use
the default value whenever possible.</para>
</entry></row>
<row><entry>FORM
<indexterm><primary>::OPTIONS directive</primary>
<secondary>FORM option</secondary></indexterm>
</entry>
<entry>
<para>controls the form of exponential notation
for the result of arithmetic
operations and built-in functions. This can be either SCIENTIFIC (in which
case only one, nonzero digit appears before the decimal point) or ENGINEERING
(in which case the power of 10 is always a multiple of 3). The default is
SCIENTIFIC. The subkeywords SCIENTIFIC or ENGINEERING must be specified as
symbols.
The package value can be retrieved using the Package class
<link linkend="mthPackageDigits">form</link> method.
</para>
</entry></row>
<row><entry>FUZZ
<indexterm><primary>::OPTIONS directive</primary>
<secondary>FUZZ option</secondary></indexterm>
</entry>
<entry>
<para>controls how many digits, at full precision, are ignored during
a numeric
comparison operation. (See <link linkend="numcom">Numeric Comparisons</link>.)
The value <emphasis role="italic">fuzz</emphasis> must be a symbol or string
that is a valid positive whole number value and must be smaller than the
current DIGIT ::OPTIONS setting.
The package value can be retrieved using the Package class
<link linkend="mthPackageDigits">fuzz</link> method.
</para>
<para>NUMERIC FUZZ temporarily
reduces the value of NUMERIC DIGITS by the NUMERIC FUZZ value during every
numeric comparison. The numbers are subtracted under a precision of DIGITS
minus FUZZ digits during the comparison and are then compared with 0.
</para>
</entry></row>
<row><entry>TRACE
<indexterm><primary>::OPTIONS directive</primary>
<secondary>TRACE option</secondary></indexterm>
</entry>
<entry>
<para>controls the tracing action (that is, how much is displayed to the user) during the processing of
all Rexx code contained in the package. Tracing describes some or all of the clauses in a program,
producing descriptions of clauses as they are processed. TRACE is mainly used for debugging. The value
<emphasis role="italic">trace</emphasis> must be one of the <link linkend="alphaco">Trace Alphabetic
Character (Word) Options</link> valid for the <link linkend="keyTrace">Trace instruction</link>. The
package value can be retrieved using the Package class <link linkend="mthPackageDigits">trace</link>
method.
</para>
</entry></row>
</tbody>
</tgroup>
</informaltable>
</section>
<section id="requ"><title>::REQUIRES</title>
<indexterm><primary>:: REQUIRES directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::REQUIRES</secondary></indexterm>
<indexterm><primary>LIBRARY subkeyword</primary>
<secondary>in a REQUIRES directive</secondary></indexterm>
<para>The ::REQUIRES directive specifies that the program requires access to
the classes and objects of the Rexx program
<emphasis role="italic">programname</emphasis>.</para>
<programlisting>
<![CDATA[
>>-::REQUIRES--"programname"--+---------+-;--------------------><
+-LIBRARY-+
]]>
</programlisting>
<para>If the LIBRARY option is not specified, all public classes and routines
defined in the named program are made available to the executing program. The
<emphasis role="italic">programname
</emphasis> is a literal string or a symbol that is
taken as a constant. The string or symbol
<emphasis role="italic">programname</emphasis> can be any string or symbol that is valid
as the target of a CALL instruction. The program <emphasis
role="italic">programname</emphasis> is called as an external routine with no
arguments. The program is searched for using normal external program search
order. See <link linkend="xsearcho">Search Order</link> for details. The main
program code, which precedes the first directive instruction, is run.
</para>
<para>If any Rexx code preceeds the first directive in
<emphasis role="italic">programname</emphasis> then that code is executed at the
time the <emphasis role="italic">::REQUIRES</emphasis> is processed by the
interpreter. This will be executed prior to executing the main Rexx program in
the file that specifies the ::REQUIRES statement.
</para>
<para>If the LIBRARY option is specified, <emphasis role="italic">programname</emphasis>
is the name of an external native library that is required by this program. The
library will be loaded using platform-specific mechanisms, which generally means
the library name is case sensitive. Any routines defined in the library will be
made available to all programs running in the process. If the native library
cannot be loaded, the program will not be permitted to run. All LIBRARY
::REQUIRES directives will be processed before ::REQUIRES for Rexx programs,
which will ensure that the native libraries are available to the initialization
code of the Rexx packages.
</para>
<para>::REQUIRES directives can be placed anywhere after the main section of
code in the package. The order of ::REQUIRES directives determines the search
order for classes and routines defined in the named programs and also the load
order of the referenced files. Once a program is loaded by a ::REQUIRES
statement in a program, other references to that same program by ::REQUIRES
statements in other programs will resolve to the previously loaded program. The
initialization code for the ::REQUIRES file will only be executed on the first
reference.
</para>
<para>The following example illustrates that two programs, ProgramA and ProgramB,
can both access classes and routines that another program, ProgramC, contains.
(The code at the beginning of ProgramC runs prior to the start of the main
Rexx program.)</para>
<mediaobject>
<imageobject>
<!-- Note! - if we include a /imagedata tag we get an error for DSSSL! -->
<imagedata fileref="MultipleRequires" scale="70">
</imageobject>
</mediaobject>
<para>The language processor uses local routine definitions within a program
in preference to routines of the same name accessed through ::REQUIRES directives.
Local class definitions within a program override classes of the same name
in other programs accessed through ::REQUIRES directives.</para>
<para>Another directive, or the end of the program, must follow a ::REQUIRES
directive. Only null clauses can appear between them.</para>
</section>
<section id="routd"><title>::ROUTINE</title>
<indexterm><primary>:: ROUTINE directive</primary></indexterm>
<indexterm><primary>directives</primary>
<secondary>::ROUTINE</secondary></indexterm>
<indexterm><primary>PUBLIC subkeyword</primary>
<secondary>in a ROUTINE directive</secondary></indexterm>
<indexterm><primary>PRIVATE subkeyword</primary>
<secondary>in a ROUTINE directive</secondary></indexterm>
<indexterm><primary>EXTERNAL subkeyword</primary>
<secondary>in a ROUTINE directive</secondary></indexterm>
<indexterm><primary>EXTERNAL subkeyword</primary>
<secondary>in a ROUTINE directive</secondary>
<tertiary>LIBRARY routine</tertiary></indexterm>
<indexterm><primary>EXTERNAL subkeyword</primary>
<secondary>in a ROUTINE directive</secondary>
<tertiary>REGISTERED routine</tertiary></indexterm>
<para>The ::ROUTINE directive creates named routines within a program.</para>
<programlisting>
<![CDATA[
+-PRIVATE-+
>>-::ROUTINE--routinename--+---------+--+---------------+-------><
+-PUBLIC--+ +-EXTERNAL-spec-+
]]>
</programlisting>
<para>The <emphasis role="italic">routinename</emphasis>
is a literal string or a symbol that is taken as a constant.
Only one ::ROUTINE directive can appear for any
<emphasis role="italic">routinename</emphasis> in a program.</para>
<para>If the EXTERNAL option is not specified, the ::ROUTINE directive starts a
routine, which is ended by another directive or the end of the program.
</para>
<para>If you specify the PUBLIC option, the routine is visible beyond its containing
Rexx program to any other program that references this program with a ::REQUIRES
directive. If you do not specify the PUBLIC option, the routine is visible
only within its containing Rexx program.</para>
<para>Routines you define with the ::ROUTINE directive behave like external routines.
In the search order for routines, they follow internal routines and built-in
functions but precede all other external routines.</para>
<para><emphasis role="bold">Example:</emphasis></para>
<indexterm><primary>examples</primary>
<secondary>::ROUTINE directive</secondary></indexterm>
<programlisting>
::class c
::method a
call r "A" /* displays "In method A" */
::method b
call r "B" /* displays "In method B" */
::routine r
use arg name
say "In method" name
</programlisting>
<para>If the EXTERNAL option is specified, then <emphasis role="italic">spec</emphasis>
identifies a routine in an external native library that will be defined as the
named routine for this program. The <emphasis role="italic">spec</emphasis> is
a literal string containing a series of whitespace delimited tokens defining the
external function. The first token identifies the type of native routine to
locate:</para>
<variablelist>
<varlistentry><term>LIBRARY</term>
<listitem><para>Identifies a routine in an external native library of the type
supported by the ::REQUIRES directive. The second token must identify the name
of the external library. The external library is located using
platform-specific mechanisms for loading libraries. For Unix-based systems,
the library name is case-sensitive. The third token is optional and specifies
the name of the routine within the library package. If not specified, the
::ROUTINE name is used. The routine name is not case sensitive.
</para></listitem></varlistentry>
<varlistentry><term>REGISTERED</term>
<listitem><para>Identifies a routine in an older-style Rexx function package.
The second token must identify the name of the external library. The external
library is located using platform-specific mechanisms for loading libraries.
For Unix-based systems, the library name is case-sensitive. The third token is
optional and specifies the name of the function within the library package. If
not specified, the ::ROUTINE name is used. Loading of the function will be
attempted using the name as given and as all uppercase. Using REGISTERED is the
equivalent of loading an external function using the RXFUNCADD() built-in
function. See
<link linkend="bifRxfuncadd">.METHODS</link> for more details.
</para></listitem></varlistentry>
</variablelist>
<para><emphasis role="bold">Example:</emphasis></para>
<indexterm><primary>examples</primary>
<secondary>::ROUTINE directive</secondary>
<tertiary>EXTERNAL option</tertiary></indexterm>
<programlisting>
-- load a function from rxmath library
::routine RxCalcPi EXTERNAL "LIBRARY rxmath"
-- same function, but a different internal name
::routine Pi EXTERNAL "LIBRARY rxmath RxCalcPi"
-- same as call rxfuncadd "SQLLoadFuncs", "rexxsql", "SQLLoadFuncs"
::routine SQLLoadFuncs "REGISTERED rexxsql SQLLoadFuncs"
</programlisting>
<para><emphasis role="bold">Notes:</emphasis></para>
<orderedlist>
<listitem><para>It is an error to specify ::ROUTINE with the same routine name more than
once in the same program. It is not an error to have a local ::ROUTINE with
the same name as another ::ROUTINE in another program that the ::REQUIRES
directive accesses. The language processor uses the local ::ROUTINE definition
in this case.</para></listitem>
<listitem><para>Calling an external Rexx program as a function is similar to calling an
internal routine. For an external routine, however, the caller's variables
are hidden and the internal values (NUMERIC settings, for example) start with
their defaults.</para></listitem>
</orderedlist>
<note><title>Note</title>
<para>If you specify the same ::ROUTINE
<emphasis role="italic">routinename</emphasis> more than once in different
programs, the last one is used. Using more than one ::ROUTINE
<emphasis role="italic">routinename</emphasis> in the same program produces
an error.</para></note>
</section>
</chapter>