Project

General

Profile

Parameter Passing

Approach

INPUT Parameters

INPUT-OUTPUT and OUTPUT Parameters

Function or procedure parameters can be modified in the called code. If the parameter has INPUT-OUTPUT or OUTPUT type, any modifications will be visible by the calling code.

Primitives cannot be directly used since in Java there is no such thing as a reference to a primitive. That means that the modifications of primitives passed as parameters cannot be seen by the calling code.

Java object wrappers cannot be used directly since they are immutable. This means that the content of the object passed by reference to a Java object wrapper (e.g. Integer) cannot be modified in the called code. The called code can assign the reference to another object, but as that reference is passed by value in Java, this does not affect the reference in the calling code.

The solution is to create mutable FWD wrapper classes for each data type.

ASSIGN Database Trigger Parameter

A database trigger that is invoked when the associated field is assigned, passing the old field's value as a named parameter. Specified as a TRIGGER PROCEDURE or in an ON statement.

TBD

Constructor Parameter

Object-oriented 4GL extensions allow class definitions. Class definitions may contain a CONSTRUCTOR statement (a special method called to create a new instance of the object). Parameters to the constructor are local variables that are scoped to that method.

DEFINE PARAMETER

This statement specifies a parameter for an external procedure or internal procedure. This statement determines the data type, mode and ordinal position in the procedure's signature. In particular, the ordinal position is determined by the order of the DEFINE PARAMETER statements, where the 1st DEFINE PARAMETER statement in the procedure is the 1st parameter and so forth. To invoke the procedure, the corresponding parameter(s) must be specified in the RUN statement (with the same type, mode and order as defined in the procedure itself).

At a high level, Progress 4GL has 7 main forms of this statement. The following summarizes FWD support for these forms:

Form Description Supported Notes
DEFINE <mode> PARAMETER <parm_name> { AS | LIKE } <primitive_type> [variable_options]. Defines a parameter in which the caller will pass a reference to a variable (INPUT-OUTPUT or OUTPUT mode) or a value of an expression (@INPUT* mode). Yes The following are NOT supported:
     DLL and UNIX shared library access (RETURN mode, data types)
     data types which are not yet supported by FWD (see the Variables section of this chapter)
     EXTENT (array) parameters
     ActiveX control event procedures
DEFINE <mode> PARAMETER <parm_name> AS [CLASS] <class_name> [EXTENT <num_elements>]. Defines a parameter that is an instance of the specified class. No  
DEFINE PARAMETER BUFFER <buffername> FOR [TEMP-TABLE] <table> [PRESELECT]. Defines a parameter in which the caller will pass a reference to a buffer (always INPUT-OUTPUT mode) that accesses a temp-table or database table. Yes See Part 5 of this book for details.
DEFINE <mode> PARAMETER TABLE FOR <temp_table_name> [table_options]. Defines a parameter in which the caller will pass a temp-table by reference or by value. Yes See Part 5 of this book for details.
DEFINE <mode> PARAMETER TABLE-HANDLE <temp_table_handle> [table_options]. Defines a parameter in which the caller will pass a handle to a temp-table. No See Part 5 of this book for details.
DEFINE <mode> PARAMETER DATASET FOR <dataset_name> [table_options]. Defines a parameter in which the caller will pass a Pro-Dataset by reference or by value. No See Part 5 of this book for details.
DEFINE <mode> PARAMETER DATASET-HANDLE <dataset_handle> [table_options]. Defines a parameter in which the caller will pass a handle to a Pro-Dataset. No See Part 5 of this book for details.

This section of the book will only describe how the common or "variable" form of this statement is converted. When the CLASS form is supported, this section will also describe that support. All other forms are database-related and thus are described in Part 5 of this book.

The supported modes are INPUT, INPUT-OUTPUT and OUTPUT. RETURN is not supported (in Progress 4GL it is only used for DLL access and FWD does not provide DLL access yet). All data types which are supported in FWD as variables can be used as parameter types. The use of both AS and LIKE are supported.

The following is a simple 4GL example showing parameters of each supported mode type and the core options:

define input        parameter txt1  as character.
define input-output parameter num2  as integer.
define output       parameter dat3  as date.
define input        parameter txt4  as character  case-sensitive.
define input-output parameter dec5  as decimal    decimals 2   no-undo.
define output       parameter log6  as logical    initial true.

If this code is in an external procedure, the resulting Java code will look like this (the comments have been added by hand to make it easier to understand):

public void execute(final character _txt1, final integer num2, final date dat3,
                    final character _txt4, final decimal dec5, final logical log6)
{
   externalProcedure(new Block()
   {
      // these member variables are copies of input parameters that were passed in, any edits
      // will not be "visible" in the calling code

      character txt1 = new character(_txt1);

      character txt4 = new character(_txt4);

      public void init()
      {
         // all parameters are UNDO by default; each undoable variable must be registered here
         // and all NO-UNDO variables must be excluded
         TransactionManager.register(txt1, num2, dat3, txt4, log6);

         // output parameters must be initialized to their default value or to the value given
         // in an initializer option (for date variables the default is the unknown value)
         dat3.assign(date.instantiateUnknownDate());
         log6.assign(new logical(true));

         // options other than initializers
         txt4.setCaseSensitive(true);
         dec5.setPrecision(2);

         // any INPUT-OUTPUT or OUTPUT parameters that are NO-UNDO will be configured here
         TransactionManager.deregister(new Undoable[]
         {
            dec5
         });
      }

      public void body()
      {
         // all parameters can be accessed here by name as needed
      }

   });
}

Parameters are emitted the same way for both internal procedures and external procedures. The above example is of an external procedure, but for an internal procedure, only the method name would be different (instead of execute() it would be named a valid Java name based on the 4GL internal procedure name) and the externalProcedure() call would be changed to an internalProcedure() call.

All parameters are final. Since the replacement for 4GL assignment in FWD calls a method (usually BaseDataType.assign()), there are no conditions in which a named parameter reference must be assigned a different reference using the Java assignment operator (=). This means that final can be used for all parameters. The primary requirement for doing this is to allow all inner classes to be able to directly refer to these parameters. Since all the 4GL block behavior is implemented using anonymous inner classes, this simplifies the resulting code.

Each data type will be directly mapped from the 4GL type to the FWD replacement type.

The FWD conversion uses its 4GL to Java name conversion routines to create a unique Java variable name for each parameter, based on the original 4GL parameter name. All references to that parameter will likewise use that same converted name. For details on how parameter names convert, please see the Naming section of the Other Customization chapter of the FWD Conversion Handbook. Parameter naming works the same as variable naming.

INPUT-OUTPUT and OUTPUT parameters must by nature be shared references with the calling code. This means that the converted code will directly use the reference passed in as a parameter. These parameter references will use the same Java name as is named in the method signature for the internal or external procedure.

INPUT parameters must by nature be a one-way transfer of data from the caller to the called code. This means that the called code cannot directly refer to the same reference as is given in the method signature. Just as in Java, in the 4GL it is valid to modify an INPUT parameter. This means that the called code must have its own local copy of the parameter so that changes are not visible in any reference provided by the caller. To achieve this, the parameter name in the method signature will be the converted Java name prefixed by an underscore (_) character. In the above example, the 4GL INPUT parameter txt1 is named _txt1 in the method signature. Then inside the anonymous inner class (see new Block() { … } above), there will be a "properly" named member variable of the same type. This is the local copy of the INPUT parameter which can be directly referenced by the converted code. Each local copy is initialized from the matching parameter passed in. So in this example, txt1 is initialized from the _txt1 passed in reference. Since the local copy is a member of the anonymous inner class, it effectively has the same scope as the rest of the parameters.

All other options and initialization code will emit inside the Block.init() method. This is a method that is only called once, it is never executed again (even during the equivalent of a 4GL "retry") and it is called before the Block.body() is executed. This makes it perfect for initialization code.

All procedure parameters are enabled for UNDO by default (in FWD terms they are "undoable"). All undoable parameters will be listed in a TransactionManager.register() method call (it takes a variable argument list) and any NO-UNDO parameters will be excluded from that call.

INPUT-OUTPUT and OUTPUT parameters can optionally be specified as NO-UNDO. The NO-UNDO parameters will be passed in an Undoable[] to TransactionManager.deregister(). The reason this is necessary is that by definition, INPUT-OUTPUT and OUTPUT parameters already exist in a block somewhere in the calling code. This means that they may already be registered for UNDO support in the calling code. To properly implement NO-UNDO, it is necessary to de-register those instances from the UNDO lists for the called code, while leaving the UNDO lists for the calling code unchanged. This is why it is not enough to just avoid the register() method call.

Any initialization for parameters (using the INITIAL option) will be emitted in the init() method. These initializers will emit as assign() method calls using the literals specified in the INITIAL option. Since OUTPUT parameters must also have a default value assigned, if there is no explicit INITIAL option, any OUTPUT parameter will be initialized to its default value. For all variable types (except date), the default value is implemented by the default constructor for the wrapper class. For date, the default constructor creates an instance with today's date (the same as the TODAY built-in function). But since the 4GL date instance will default to unknown value, to properly initialize it, the date.instantiateUnknownDate() static method is used. INPUT and INPUT-OUTPUT parameters are not initialized unless there is an explicit INITIAL option.

User-interface specific options are removed from the replacement business logic but their settings will be honored in any frames or user-interface processing that reference that parameter.

Other options that are supported are CASE-SENSITIVE, NOT CASE-SENSITIVE and DECIMALS. These options are set into the parameter instances in the init() method, just as described in the section below entitled Data Type Options.

Options summary:

Option Description Supported Notes
CASE-SENSITIVE The character parameter will be compared and sorted on a case-sensitive basis. Yes See Data Type Options below.
COLUMN-LABEL When this parameter is used as a widget in a frame, this defines the descriptive text column label for the widget. Yes See Part 6 of this book.
DECIMALS Sets the number of digits to the right of the decimal point for this decimal parameter. Yes See Data Type Options below.
EXTENT Defines an array parameter with a specific number of elements. No See Data Type Options below.
FORMAT Specifies the pattern used to format the output of this parameter when used as a widget in a frame. Yes See Part 6 of this book.
INITIAL Defines an explicit initial value for the parameter. Yes See Data Type Options below.
LABEL When this parameter is used as a widget in a frame, this defines the descriptive text label for the widget. Yes See Part 6 of this book.
NO-UNDO UNDO support is disabled for the parameter. Yes See UNDO below.
NOT CASE-SENSITIVE The character parameter will be compared and sorted on a case-insensitive basis. Yes See Data Type Options below.

Function Parameter

This statement specifies a parameter for a user-defined function. This statement determines the data type, mode and ordinal position in the function's signature. In particular, the ordinal position is determined by the order of the parameters listed in the FUNCTION statement. To invoke the function, the corresponding parameter(s) must be specified in the function call (with the same type, mode and order as defined in the FUNCTION statement itself).

At a high level, Progress 4GL has 7 main forms of this statement. The following summarizes FWD support for these forms:

Form Description Supported Notes
<mode> <parm_name> AS <primitive_type> [EXTENT <num_elements>] Defines a parameter in which the caller will pass a reference to a variable (INPUT-OUTPUT or OUTPUT mode) or a value of an expression (INPUT mode). Yes The following are NOT supported:
     data types which are not yet supported by FWD (see the Variables section of this chapter)
     EXTENT (array) parameters
<mode> <parm_name> AS [CLASS] <class_name> [EXTENT <num_elements>] Defines a parameter that is an instance of the specified class. No  
BUFFER <buffername> FOR <table> [PRESELECT] Defines a parameter in which the caller will pass a reference to a buffer (always INPUT-OUTPUT mode) that accesses a temp-table or database table. Yes See Part 5 of this book for details.
<mode> TABLE <temp_table_name> [table_options] Defines a parameter in which the caller will pass a temp-table by reference or by value. Yes See Part 5 of this book for details.
<mode> TABLE-HANDLE <temp_table_handle> [table_options] Defines a parameter in which the caller will pass a handle to a temp-table. No See Part 5 of this book for details.
<mode> DATASET <dataset_name> [table_options] Defines a parameter in which the caller will pass a Pro-Dataset by reference or by value. No See Part 5 of this book for details.
<mode> DATASET-HANDLE <dataset_handle> [table_options] Defines a parameter in which the caller will pass a handle to a Pro-Dataset. No See Part 5 of this book for details.

This section of the book will describe how the common or "variable" form of this statement is converted. When the CLASS form is supported, this section will also describe that conversion. All other forms are database-related and thus are described in Part 5 of this book.

The supported modes are INPUT, INPUT-OUTPUT and OUTPUT. All data types which are supported in FWD as variables can be used as parameter types. The 4GL syntax and the Java converted code are very similar to that in the DEFINE PARAMETER statement. The following is a list of the key differences (all of these match up with differences in how the 4GL works):

  • All function parameters are always NO-UNDO. This means that function parameters are never added to the TransactionManager.register() method call. More importantly, INPUT-OUTPUT and OUTPUT mode function parameters are always added to a TransactionManager.deregister() method call to ensure that any preexisting UNDO reference to those variables in the calling procedure is temporarily removed for the scope of the function.
  • There are never any options that can be specified for a function parameter. EXTENT is possible in later 4GL versions but is not supported yet in FWD.
  • Since there is no INITIAL option (and no alternative 4GL syntax for an explicit initializer), there is no way to set the initial value of a function parameter. OUTPUT mode parameters do get initialized, but as in the 4GL, they are always initialized to the unknown value.
  • In some cases, the mode can be left unspecified in the 4GL code. Any unspecified mode is the same as an INPUT mode parameter.

The following is a 4GL example:

function example returns integer (input        txt1  as character,
                                  input-output num2  as integer,
                                  output       dat3  as date):
   return 0.
end.

This is the resulting Java code:

public integer example(final character _txt1, final integer num2, final date dat3)
{
   return integerFunction(new Block()
   {
      character txt1 = new character(_txt1);

      public void init()
      {
         TransactionManager.deregister(new Undoable[]
         {
            num2,
            dat3
         });
         dat3.assign(date.instantiateUnknownDate());
      }

      public void body()
      {
         returnNormal(0);
      }
   });
}

Please see the DEFINE PARAMETER section above for more details on why the Java code emits in this manner.

Method Parameter

This is part of the class support in v10 4GL. User-defined methods can be created as part of a class and each method can have a custom parameter list.

Property Setter Parameter

This is an optional method that can encode logic that is executed when a property is assigned (see DEFINE PROPERTY above). There cannot be more than one parameter for this special setter method.


© 2004-2022 Golden Code Development Corporation. ALL RIGHTS RESERVED.