FUNCTION Block

Purpose

Defines a subroutine that Net.Data invokes from the macro. The executable statements in a FUNCTION block can be inline statements directly interpreted by a language environment, or they can be a call to an external program.

EXEC Blocks in Function Blocks

If you use the EXEC block within the FUNCTION block, it must be the only executable statement in the FUNCTION block. Before passing the executable statement to the language environment, Net.Data appends the file name of the program in the EXEC block to a path name determined by the EXEC_PATH path configuration statement in the initialization file. The resulting string is passed to the language environment to be executed.

The method that the language environment uses to process the EXEC block depends on the particular language environment; the REXX, System, and Perl Net.Data-provided language environments support the EXEC block.

Using Special Characters in Language Statements

When characters that match Net.Data language constructs syntax are used in the language statements section of a function block as part of syntactically valid embedded program code (such as REXX or Perl), they can be misinterpreted as Net.Data language constructs, causing errors or unpredictable results in a macro.

For example, a Perl function might use the COMMENT block delimiter characters, %{. When the macro is run, the %{ characters are interpreted as the beginning of a COMMENT block. Net.Data then looks for the end of the COMMENT block, which it thinks it finds when it reads the end of the function block. Net.Data then proceeds to look for the end of the function block, and when it can't be found, issues an error.

Use one of the following methods to use Net.Data special characters as part of your embedded program code, without having them interpreted by Net.Data as special characters:

For example, the following Perl function contains characters representing a COMMENT block delimiter, %{, as part of its Perl language statements:

%function(DTW_PERL) func() {
  ...           
  for $num_words (sort bynumber keys %{ $Rtitles{$num} }) {
     &make_links($Rtitles{$num}{$num_words});          
  }            
  ...         
 %}   

To ensure that Net.Data interprets the %{ characters as Perl source code rather than as a Net.Data COMMENT block delimiter, rewrite the function in either of the following ways:

Syntax

>>-%FUNCTION--(--lang_env--)--function_name--| parm passing spec |-->
 
     .-;---------------------------------------------.
>----+-| returns spec |--{--| function body |----%}--+---------><
 
parm passing spec
 
|---(--+---------------------------------------------+---)------|
       |  .-,-------------------------------------.  |
       |  |      (1)                              |  |
       |  V .-IN-------.                          |  |
       '----+----------+---+-----------+---name---+--'
            +-OUT------+   '-datatype--'
            '-INOUT----'
 
returns spec
 
|---+----------------------+------------------------------------|
    '-RETURNS--(--name--)--'
 
function body
 
|---+-------------------------------+--------------------------->
    |  .--------------------------. |
    |  V                          | |
    +----inline statement block---+-+
    '-exec block--------------------'
 
>-----+-----------------------------------------------+---------|
      |  .---------------------.                      |
      |  V               (2)   |                      |
      +----report block--------+---+----------------+-+
      |                            '-message block--' |
      |                .--------------------------.   |
      |                V                          |   |
      '-message block-----+--------------------+--+---'
                          |              (2)   |
                          '-report block-------'
 

Notes:

  1. The default parameter type of IN applies when no parameter type is specified at the beginning of the parameter list. A parameter without a parameter type uses the type most recently specified in the parameter list, or type IN if no type has been specified. For example, in the parameter list (parm1, INOUT parm2, parm3, OUT parm4, parm5), parameters parm1, parm3, and parm5 do not have parameter types. The parameter parm1 has a type of IN because no initial parameter type has been specified. The parameter parm3 has a type of INOUT because it is the most recently specified parameter type. Similarly, the parameter parm5 has a type of OUT because it is the most recently specified type in the parameter list.

  2. The repeated report block is valid for:

Values

%FUNCTION
The keyword that specifies a subroutine that Net.Data invokes from the macro.

lang_env
The language environment that processes the function body. See the Net.Data Administration and Programming Guide for more information.

function_name
The name of the function being defined that can be an alphabetic or numeric string that begins with an alphabetic character or underscore and contains any combination of alphabetic, numeric, or underscore characters.

parm passing spec:

IN
Specifies that Net.Data passes input data to the language environment. IN is the default.

OUT
Specifies that the language environment returns output data to Net.Data.

INOUT
Specifies that Net.Data passes input data to the language environment and the language environment returns output data to Net.Data.

datatype
Specifies the datatype of the paramater. For a list of supported datatypes for stored prodedures, see the operating system appendix of Net.Data Reference.

name
An alphabetic or numeric string beginning with an alphabetic character or underscore and containing any combination of alphabetic, numeric, or underscore characters.

returns spec:

RETURNS
Declares the variable that contains the function value assigned by the language environment, after the function completes.

function body:

inline statement block
Syntactically valid statements from the language environment specified in the function definition, for example; REXX, SQL, or Perl. See Net.Data Administration and Programming Guide for a description of the language environment you are using. See the programming language's programming reference for syntax and usage. The string representing the inline statement block can contain Net.Data variable references and function calls, which get evaluated before execution of the inline statement block (program).

exec block
The EXEC block. The name of an external program that executes when the function is called. See EXEC Block or Statement for syntax and examples.

report block
The REPORT block. Formatting instructions for the output of a function call. You can use header and footer information for the report. See REPORT Block for syntax and examples.

message block
The MESSAGE block. A set of return codes, the associated messages, and the actions Net.Data takes when a function call is returned. See MESSAGE Block for syntax and examples.

Context

The FUNCTION block can be found in these contexts:

Restrictions

Examples

The following examples are general and do not cover all language environments. See Net.Data Language Environment Reference for more information about using FUNCTION blocks with a specific language environment.

Example 1: A REXX substring function

%DEFINE lstring = "longstring"
%FUNCTION(DTW_REXX) substring(IN x, y, z) RETURNS(s) {
  s = substr("$(x)", $(y), $(z));
%}
%DEFINE a = {@substring(lstring, "1", "4")%} %{ assigns "long" to a %}

When a is evaluated, the @substring function call is found and the substring FUNCTION block is executed. Variables are substituted in the executable statements in the FUNCTION block, then the text string s = substr("longstring", 1, 4) is passed to the REXX interpreter to execute. Because the RETURNS clause is specified, the value of the @substring function call in the evaluation of a is replaced with "long", the value of s.

Example 2: Invoking an external REXX program

The EXEC statement tells the REXX language environment to tell the REXX interpreter to execute the external REXX program mypgm.cmd. Because the REXX language environment can directly share Net.Data variables with the REXX program, it assigns the REXX variables a, b, and c the values of the Net.Data variables w, x and y before executing mypgm.cmd. mypgm.cmd can directly use the variables a, b, and c in REXX statements. When the program ends, the REXX variables a, b, and d are retrieved from the REXX program, and their values are assigned to the Net.Data variables w, x, and z. Because the RETURNS clause is not used in the definition of the my_rexx_pgm FUNCTION block, the value of the @my_rexx_pgm function call is the null string, "", (if the return code is 0) or the value of the REXX program return code (if the return code is nonzero).

Example 3: An SQL query and report

%FUNCTION(DTW_SQL) query_1(IN x, IN y) {
   SELECT customer.num, order.num, part.num, status
   FROM customer, order, shippingpart
   WHERE customer.num = '$(x)'
      AND customer.ordernumber = order.num
      AND order.num = '$(y)'
      AND order.partnumber = part.num
   %REPORT{
     <p>Here is the status of your order:
     <p>$(NLIST)
     <ul>
     %ROW{
       <li>$(V1)  $(V2)  $(V3)  $(V4)
     %}
     </ul>
        %}
%}
%DEFINE customer_name="IBM"
%DEFINE customer_order="12345"
%HTML(REPORT) {
  @query_1(customer_name, customer_order)
%}

The @query_1 function call substitutes IBM for $(x) and 12345 for $(y) in the SELECT statement. Because the definition of the SQL function query_1 does not identify an output table variable, the default table is used (see the TABLE variables block for details). The NLIST and Vi variables referenced in the REPORT block are defined by the default table definition. The report produced by the REPORT block is placed in the output HTML where the query_1 function is invoked.

Example 4: A system call to execute a Perl script

The System language environment interprets the executable statements in a FUNCTION block by passing them to the operating system through the C language system() function call. This method does not allow Net.Data variables to be directly passed or retrieved to the executable statements, as the REXX language environment does, so the System language environment passes and retrieves variables as described here:

When the @today function call is encountered, Net.Data performs variable substitution on the executable statements. In this example, there are no Net.Data variables in the executable statements, so no variable substitution is performed. The executable statements and parameters are passed to the System language environment, which creates a named pipe and sets the environment variable DTWPIPE to the name of the pipe.

Then the external program is called with the C system() function call. The external program opens the pipe as write-only and writes the values of output parameters to the pipe as if it were a standard stream file. The external program generates HTML output by writing to STDOUT. In this example, the output of the system date program is assigned to the variable result, which is the variable identified in the RETURNS clause of the FUNCTION block. This value of the result variable replaces the @today() function call in the HTML block.

Example 5: Perl language environment

%FUNCTION(DTW_PERL) today() RETURNS(result) {
  $date = `date`;
  chop $date;
  open(DTW, "> $ENV{DTWPIPE}") || die "Could not open: $!";
  print DTW "result = \"$date\"\n";
%}
%HTML(INPUT) {
  @today()
%}

Compare this example with Example 4 to see how the EXEC block is used. In Example 4, the System language environment does not understand how to interpret Perl programs, but the language environment does know how to call external programs. The EXEC block tells it to call a program called perl as an external program. The actual Perl language statements are interpreted by the external Perl program. Example 5 has no EXEC block, because the Perl language environment is able to directly interpret Perl language statements.


[ Top of Page | Previous Page | Next Page | Index ]