( parameter [ , parameter ] ... )
|
The parameters specified by parameter must match in number and order, according to mode and data type, as required by the given procedure, user-defined function, method, or constructor definition. Use the following syntax to specify each
parameter:
[ INPUT | OUTPUT | INPUT-OUTPUT ]
{ parm [ AS data-type ]
| { { TABLE temp-table-name
| TABLE-HANDLE temp-table-handle
| DATASET dataset-name
| DATASET-HANDLE dataset-handle
} [ APPEND ] [ BY-VALUE | BY-REFERENCE | BIND ]
}
}
|
[ INPUT
| OUTPUT
| INPUT-OUTPUT
]
|
|
|
|
|
|
|
If the method is overloaded by a given parameter only by mode, you must specify the mode for this parameter in the method call. If you do not do so, ABL raises a compile-time ambiguity error. For example, if a method is overloaded twice by an INTEGER parameter, and the parameter for one method definition has the INPUT mode while the parameter for the other method definition has the OUTPUT mode, you must specify the INPUT keyword if you intend to use the method defined with the INPUT parameter.
|
|
|
When identifying the parameter mode for a .NET method or constructor, each .NET language uses its own keyword syntax to identify it.
Table 51 shows the C# parameter syntax that corresponds to an ABL parameter specified with a given mode. Note that in C#, the default (no keyword) corresponds to the ABL INPUT mode.
Also note, as with ABL class-based methods, the default parameter passing modes for calling .NET methods and constructors are based on the parameter passing modes defined for the method or constructor prototypes, depending on overloading. Thus, you
must specify the parameter passing mode for each affected parameter if the method is overloaded
only by a given parameter’s mode.
Note:
|
Syntactic limitations require that none of the following data items can be an OUTPUT or INPUT-OUTPUT parameter: a writable handle attribute, a writable property (ABL or .NET) on an object reference, or a data member (ABL or .NET) on an object reference. The limitation is that OUTPUT and INPUT-OUTPUT parameters cannot have a colon in their syntax. For example, OUTPUT myObjectRef:WritableProperty is invalid syntax.
|
For procedures, the data type of parm must be compatible with the data type defined for the parameter. Procedures allow the matching of a wide variety of different data types between the passed parameter and the parameter definition. When it can, the AVM converts the passed value from the source data type to an appropriate value in the destination data type, depending on the direction (parameter mode) of the passed value. For procedures, the AVM checks data type matching and appropriate overflow conditions at run time.
The AVM implicitly converts passed parameter values of certain data types from a narrow data type in the source to a widened data type in the destination, depending on the parameter mode. A widened data type is one that can hold all the values of a narrower data type without loss of data. Widening is supported for three related sets of data types, as shown in
Table 52, where the arrow (
→ ) indicates the direction that a value can be passed for the parameter.
|
INPUT parameters — The data type of the passed parameter can be narrower than the defined parameter.
|
|
OUTPUT parameters — The data type of the passed parameter can be wider than the defined parameter.
|
|
INPUT-OUTPUT parameters — Widening is not supported. Because values are passed in both directions, the data type of the passed parameter must exactly match the data type of the defined parameter.
|
For .NET method parameters, ABL also supports widening relationships between ABL and some .NET data types. For more information, see the notes of this reference entry.
For a parm that involves .NET data types, either as the parameter definition or as the argument, the requirements for parameter passing depend on the parameter and argument data types and the type of routine that defines the parameter.
Table 53 shows the possible combinations.
Note:
|
Table 53 refers to .NET value types, .NET mapped data types, .NET arrays of mapped types, boxing, and unboxing. Boxing and unboxing refer to a .NET mechanism for converting between .NET value types and .NET object types. ABL supports a similar mechanism for converting between ABL primitive or array types and a .NET System.Object or compatible array object type. For more information on .NET data types, concepts, and compatibility, see the Data types reference entry.
|
|
|
|
|
|
The same .NET data type (for example, a .NET property), any corresponding ABL primitive type (as shown in Table 243), and on OUTPUT only, a System.Object4
|
|
|
|
|
|
A compatible .NET or ABL array type 7,8, and on OUTPUT only, a System.Array, System.Object, or Progress.Lang.Object
|
|
|
A compatible .NET array type 8,11, and on OUTPUT only, a System.Array, System.Object, or Progress.Lang.Object
|
|
|
On INPUT, any .NET array object type or compatible ABL array type 12, and on OUTPUT only, a System.Array, System.Object, or Progress.Lang.Object
|
|
|
On INPUT, any .NET array object type 11, and on OUTPUT only, a System.Array, System.Object, or Progress.Lang.Object
|
|
|
On INPUT, any .NET object type, an ABL primitive type, or compatible ABL array type 12, and on OUTPUT only, a System.Object or Progress.Lang.Object
|
|
|
On INPUT, any .NET object type 11, and on OUTPUT only, a System.Object or Progress.Lang.Object
|
Any .NET object type (except those in the previous rows)
|
|
Any compatible .NET object type, and on OUTPUT only, a System.Object or a Progress.Lang.Object
|
Any .NET object type (except those in the previous rows)
|
|
Any compatible .NET object type, and on OUTPUT only, a System.Object or a Progress.Lang.Object
|
|
|
|
|
|
|
|
|
|
Indicates an explicit mapping between an argument with an ABL primitive type and the parameter of a .NET method or constructor. Assuming that the .NET data type defined for the parameter is compatible with the data type of the ABL argument,
data-type represents an ABL keyword (
AS data type) that indicates an alternative .NET data type mapping to identify with the .NET parameter. This option is necessary in the following cases:
|
When the .NET method or constructor is overloaded by multiple implicit .NET data type mappings for the passed ABL primitive type and the method you want is not identified by the default match for the passed ABL data type. Thus, by explicitly specifying an AS data type, you can disambiguate the implicit .NET overloadings for the method or constructor.
|
|
The parameter is defined as a System.Object, and you want the .NET value of the passed ABL primitive type to be stored as a .NET mapped data type that is not the default match. For example, you might want the System.Object parameter to store an ABL INTEGER value as a System.Int16 instead of as a System.Int32 (the default match).
|
This parameter type can match at compile time with any TABLE parameter with the same schema, or any TABLE-HANDLE parameter. If the matching type is TABLE-HANDLE, a run-time check occurs if the TABLE-HANDLE is not the Unknown value (
?) in order to ensure that the run-time schemas match. A parameter of a user-defined function or method of a class is verified at compile time, while a parameter of a procedure is verified at run time.
This parameter type can match at compile time with any TABLE or TABLE-HANDLE parameter. If the matching type is TABLE-HANDLE, a run-time check occurs if the TABLE-HANDLE is not the Unknown value (
?) in order to ensure that the run-time schemas match. A parameter of a user-defined function or method of a class is verified at compile time, while a parameter of a procedure is verified at run time.
This parameter type can match at compile time with any DATASET parameter with the same schema, or any DATASET-HANDLE parameter. If the matching type is DATASET-HANDLE, a run-time check occurs if the DATASET-HANDLE is not the Unknown value (
?) in order to ensure that the run-time schemas match. A parameter of a user-defined function or method of a class is verified at compile time, while a parameter of a procedure is verified at run time.
This parameter type can match at compile time with any DATASET or DATASET-HANDLE parameter. If the matching type is DATASET-HANDLE, a run-time check occurs if the DATASET-HANDLE is not the Unknown value (
?) in order to ensure that the run-time schemas match. A parameter of a user-defined function or method of a class is verified at compile time, while a parameter of a procedure is verified at run time.
You can pass TABLE, TABLE-HANDLE, DATASET, and DATASET-HANDLE parameters to both local and remote procedures. These parameter types are normally passed by value, by default. That is, the calling routine and the called routine each have their own instance of the object, and the parameter is deep-copied from the calling routine’s instance to the called routine’s instance.
Passing one of these parameters to a local routine using the BY-REFERENCE option allows the calling routine and the called routine to access the same object instance. That is, both routines access the calling routine’s instance and ignore the called routine’s instance. Since the called routine’s object instance is ignored, you should define the static object as reference-only by specifying the REFERENCE-ONLY option in the DEFINE statement for the object.
When you define a reference-only object in the calling routine and pass it to the called routine using the BIND option, the AVM binds the definition of the object in the calling routine to the object instance in the called routine. When you define a reference-only object in the called routine and receive the object from the calling routine, the AVM binds the definition of the object in the called routine to the object instance in the calling routine. In either case, the reference-only object definition remains bound to the object instance until the routine containing the reference-only object definition is deleted or terminates.
The following two code fragments show how the AS data type works when calling an overloaded .NET method, in this case the
System.Math:Max( ) method. This static .NET method compares two values of the same data type and returns the largest of the two. The first fragment compiles and runs. It compares the value 50, passed as a
System.Byte (specified by the AS data type, UNSIGNED-BYTE), with the maximum value of a
System.Byte, returned by the
System.Byte:MaxValue data member. The result returned by the
Max( ) method is 255, the maximum
System.Byte value:
The second fragment compiles, but returns a run-time error. Again, it passes the same two values to the
System.Math:Max( ) method, but this time passes them as a
System.SByte (specified by the AS data type, BYTE). A signed byte parameter cannot hold positive values as large as an unsigned byte. So, passing the maximum value of a
System.Byte (unsigned byte) as a
System.SByte (signed byte) causes the
Max( ) method to raise a run-time overflow error:
|
When you call the Publish( ) event method to publish a class event, or when you execute the PUBLISH statement to publish a named event, any parameters are passed to every event handler that is subscribed to the event. However, any parameter values returned from the Publish( ) method or PUBLISH statement reflect the settings of the last event handler to execute. Therefore, when you publish a class or named event, the value returned for an OUTPUT or INPUT-OUTPUT parameter, or for a member of any object (class or handle-based) referenced in an INPUT parameter, depends on the execution order of the event handlers subscribed to the event, which is not guaranteed. In addition, for INPUT-OUTPUT parameters or for members of objects referenced by INPUT parameters, the values returned from each event handler are used as input to the next event handler that executes.
|
|
For INPUT parameters of .NET methods or constructors defined with certain .NET data types, ABL supports widening relationships that allow you to pass ABL arguments with different ABL data types than those supported for implicit mapping to .NET data types (see Table 24 in the Data types reference entry).
|
Table 54 lists the .NET parameter data types for which ABL supports the widening of ABL data types passed as INPUT arguments. For each .NET parameter data type, the listed ABL implicit mapping data type represents the closest matching ABL data type that you can pass to a .NET input parameter defined with the matching .NET data type. The corresponding listed ABL INPUT widening data types can hold smaller values that might also be acceptable to the .NET input parameter. However, they might also adhere to similar limitations as defined for passing values as the listed ABL implicit mapping data type. (Again, see
Table 24 for a more complete description of these limitations.)
|
For OUTPUT parameters of .NET methods or constructors defined with certain .NET data types, ABL supports widening relationships that allow you to pass ABL arguments with different data types than those supported for implicit mapping to .NET data types (see Table 24 in the Data types reference entry).
|
Table 55 lists the .NET parameter data types for which ABL supports the widening of ABL data types passed as OUTPUT arguments. For each .NET parameter data type, the listed ABL implicit mapping data type represents the closest matching ABL data type that can hold a .NET value passed to the OUTPUT parameter defined with the matching .NET data type. The corresponding listed ABL OUTPUT widening data types might hold even larger values than the listed ABL implicit mapping data type. However, but they might also adhere to similar limitations as defined for the listed ABL implicit mapping data type (Again, see
Table 24 for a more complete description of these limitations.)
|
If you assign a .NET value type object returned as an OUTPUT parameter from a .NET method to an ABL object reference variable, the returned object referenced in ABL is a separate copy from the original value type instance maintained by .NET. However within the ABL session, the object reference to the ABL copy, when passed as a parameter, is passed by reference like any object reference to an ABL class instance.
|
|
ABL allows you to pass ABL arrays (defined with EXTENT) and .NET array objects to each other. Passing an array parameter of any type constitutes an array assignment whose direction moves from the source to the target array according to the parameter mode. How this array assignment works for ABL and .NET array parameters depends upon the types of the source and target arrays. For more information, see the Data types reference entry.
|
|
If you pass a TABLE-HANDLE parameter to a method of a class or a class constructor, where the method or constructor is overloaded with corresponding TABLE-HANDLE and TABLE parameter definitions, the AVM executes the method or constructor that best matches the TABLE-HANDLE parameter. If the schema of the TABLE-HANDLE parameter matches the schema of the TABLE parameter definition, the AVM executes the method or constructor with the TABLE parameter definition. Otherwise, the AVM executes the method or constructor with the TABLE-HANDLE parameter definition.
|
|
If you pass a DATASET-HANDLE parameter to a method of a class or a class constructor, where the method or constructor is overloaded with corresponding DATASET-HANDLE and DATASET parameter definitions, the AVM executes the method or constructor that best matches the DATASET-HANDLE parameter. If the schema of the DATASET-HANDLE parameter matches the schema of the DATASET parameter definition, the AVM executes the method or constructor with the DATASET parameter definition. Otherwise, the AVM executes the method or constructor with the DATASET-HANDLE parameter definition.
|
If you pass a DATASET parameter to a similarly overloaded method or constructor, the AVM executes the method or constructor with a matching DATASET parameter definition. If the AVM cannot identify a method or constructor with a matching DATASET parameter definition, it executes the method or constructor with the corresponding DATASET-HANDLE parameter definition.
|
If you pass a class instance to overloaded methods or constructors whose corresponding class parameters differ only within the same class hierarchy, ABL looks from the bottom of the class hierarchy, starting with the most derived class, and chooses any method or constructor whose corresponding parameters are defined for the same class as the passed parameter. Otherwise, the AVM chooses any method or constructor whose corresponding parameters are defined for the most derived class in the same class hierarchy, which is also a super class of the passed parameter.
|
|
If you pass a class instance to overloaded methods or constructors whose corresponding class parameters differ by one or more interfaces that the class implements, only a method or constructor whose corresponding class parameter exactly matches the class of the passed parameter is acceptable to the compiler. Otherwise, the AVM generates a compile-time error for ambiguity, as one implemented interface is no better match than another.
|
|
If you pass the Unknown value ( ?) to a parameter of an overloaded method or constructor, the AVM only selects the correct method or constructor to execute when passing the Unknown value ( ?) causes no ambiguity among them. Otherwise, the AVM generates a compile-time error for ambiguity.
|
|
If you pass an ABL expression to an overloaded method or constructor whose data type cannot be known at compile-time (for example, the BUFFER-VALUE attribute), the AVM can only call the correct method or constructor at run time, and only when the overloaded method or constructor differs by more than the parameter with an unknown data type. Otherwise, the AVM raises a run-time error for ambiguity.
|
|
Convert the Unknown value ( ?) or expression to a specific data type using the appropriate ABL data type conversion function to pass the value.
|
|
Assign the Unknown value ( ?) or expression to a variable of a specific data type to pass the value.
|
|
If you pass a method of a class as a parameter to another method, constructor, procedure, or user-defined function that you invoke, and the method parameter executes the RETURN statement with the ERROR option, the method, constructor, procedure, or user-defined function that you invoke does not run. The AVM then raises ERROR on the invoked method, constructor, or procedure. The AVM does not raise ERROR on an invoked user-defined function.
|
Assignment (=) statement,
Expression,
FUNCTION statement,
NEW function (classes),
Publish( ) event method,
PUBLISH statement,
RUN statement,
RUN SUPER statement,
SUPER statement,
SUPER system reference,
THIS-OBJECT statement