| function-name |
(< [([prototype-clause] [intermediate-result-clause])]
|
[parameter] [,[parameter]] … >) |
| [array-index-expression] |
Eine Erläuterung der in dem Syntax-Diagramm verwendeten Symbole entnehmen Sie dem Abschnitt Syntax-Symbole.
Verwandte Statements: DEFINE
PROTOTYPE | DEFINE
FUNCTION
Dieser Abschnitt behandelt folgende Themen:
Ein Function Call wird verwendet, um ein Natural-Objekt des Typs Function aufzurufen.
Definiert wird die Function mit dem Natural-Statement DEFINE FUNCTION, das Folgendes enthält: die Parameter, lokale
und anwendungsunabhängige Variablen, den zu benutzenden Ergebniswert und die Statements,
die ausgeführt werden sollen, wenn die Function aufgerufen wird.
Um eine Function aufzurufen können Sie Folgendes angeben:
entweder den Namen der Function, so wie er im DEFINE FUNCTION-Statement definiert ist,
oder eine alphanumerische Variable, die den Namen der Function zur Laufzeit enthält.
In diesem Fall muss die Variable mit dem Schlüsselwort VARIABLE in einem
DEFINE
PROTOTYPE-Statement referenziert werden.
Ein Function Call kann anstelle eines schreibgeschützten Operanden in einem Natural-Statement verwendet werden. In diesem Fall muss die Function ein Ergebnis zurückgeben, welches dann von dem Statement wie ein Feld verarbeitet wird, das den gleichen Wert enthält.
Außerdem kann ein Function Call anstelle eines Natural-Statements benutzt werden. In diesem Fall braucht die Function keinen Ergebniswert zurückzugeben; falls doch, wird der Wert des Ergebnisses verworfen.
An folgenden Stellen dürfen keine Function Calls benutzt werden:
Stellen, an denen der Operand-Wert durch das Natural-Statement geändert wird, zum Beispiel:
MOVE 1 TO #FCT(<..>);
in einem DEFINE DATA-Statement;
alle einem Datenbankzugriff-Statement, zum Beispiel READ,
FIND, SELECT, UPDATE und STORE);
AT BREAK-Statement oder IF BREAK-Statement;
als Argument von Natural-Systemfunktionen (zum Beispiel AVER, SUM, *TRIM),
in einem Array-Index-Ausdruck;
als Parameter eines Function Call.
Wenn ein Function Call in einem INPUT-Statement benutzt wird, dann wird der Rückgabewert wie
ein konstanter Wert behandelt. Dies führt zur automatischen Zuweisung des Attributs
AD=O, damit dieses Feld schreibgeschützt, d.h. nur zur
Ausgabe verfügbar gemacht wird.
Operanden-Definitionstabelle:
| Operand | Mögliche Struktur | Mögliche Formate | Referenzierung erlaubt | Dynam. Definition | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function-name
|
S | A | A | U | ja | nein | |||||||||||||
Syntax-Element-Beschreibung:
| Syntax-Element | Beschreibung |
|---|---|
function-name
|
Function-Name:
Als
|
prototype-clause |
Prototype-Klausel:
Siehe prototype-clause (PT=). |
intermediate-result-clause |
Intermediate Result-Klausel:
|
parameter |
Parameter-Angabe:
Siehe |
array-index-expression |
Array-Index-Notation:
Wenn das vom Function Call zurückgegebene Ergebnis ein Array ist, muss eine Index-Notation vorgesehen werden, um die angeforderten Array-Ausprägungen zu adressieren. Weitere Informationen siehe Index-Notation in Benutzervariablen. |
PT=
prototype-name |
Um eine Function zur Kompilierungszeit auflösen zu können, benötigt Natural
Parameterdefinitionen und das Ergebnis der Function. Wenn kein Prototyp mit dem
function-name, den Parametern
oder dem Ergebnis der Function übereinstimmt, können Sie mit der
prototype-clause einen passenden Prototyp
zuweisen. In diesem Fall wird stattdessen der referenzierte Prototyp benutzt, um die
Parameter- und Function-Ergebnis-Definitionen aufzulösen. Der in dem referenzierten
Prototyp deklarierte function-name wird
ignoriert.
Syntax-Element-Beschreibung:
| Syntax-Element | Beschreibung |
|---|---|
prototype-name |
Prototyp-Name:
Als
|
IR= |
|
format-length [/array-definition] |
|
||||
[(array-definition)] HANDLE OF OBJECT |
|||||||
| ( |
|
|
[/array-definition]) DYNAMIC
|
||||
Diese Klausel kann benutzt werden, um die
format-length/array
definition des Ergebniswertes für einen Function Call
anzugeben, falls weder das katalogisierte Objekt der Function noch eine
Prototyp-Definition zur Verfügung stehen. Wenn für diesen Function Call ein Prototyp
verfügbar ist oder wenn ein katalogisiertes Objekt der aufgerufenen Function existiert,
wird das mit der intermediate-result-clause
angegebene Ergebniswertformat auf Datenübertragungskompatibilität geprüft.
Syntax-Element-Beschreibung:
| Syntax-Element | Beschreibung |
|---|---|
format-length |
Format/Länge-Definition:
Das Format und die Länge des Feldes. Informationen zur Format/Längen-Definition bei Benutzervariablen siehe Format und Länge von Benutzervariablen. |
array-definition |
Array-Dimension-Definition:
In der array-definition definieren Sie die untere und die obere Grenze der Dimensionen bei einer Array-Definition. Siehe Definition von Array-Dimensionen in der Statements-Dokumentation. |
HANDLE OF OBJECT |
Object-Handle:
Wird in Verbindung mit NaturalX verwendet. Weitere Informationen siehe NaturalX im Leitfaden zur Programmierung. |
A, B or U |
Datenformat:
Mögliche Formate: alphanumerisch, binär oder Unicode bei dynamischen Variablen. |
DYNAMIC |
Dynamische Variable:
Ein Feld kann als Weitere Informationen zur Verarbeitung dynamischer Variablen siehe Dynamische Variablen. |
|
|
nX
|
|
|||||||
|
|
|
|
|
|
|||||
| operand |
(AD=
|
)
|
|||||||
Parameter werden entweder im DEFINE DATA
PARAMETER-Statement bei der Definition der Function oder in einem
DEFINE PROTOTYPE-Statement
angegeben. Die semantischen und syntaktischen Regeln, die bei den Parametern einer
Function gelten, sind die gleichen wie diejenigen, die im Parameterabschnitt von
Subprogrammen beschrieben werden. Siehe Parameter in
der Beschreibung des CALLNAT-Statement.
Wenn Sie mehrere Parameter angeben, müssen Sie diese voneinander abtrennen - entweder
mit einem Komma oder mit dem Eingabebegrenzungszeichen, das mit dem Session-Parameter
ID angegeben wird.
Falls in der Liste der Parameter Zahlen vorkommen und wenn das Komma als Dezimalzeichen
festgelegt ist (mit dem Session-Parameter DC), müssen Sie entweder das Komma mit einem
zusätzlichen Leerzeichen vom Wert trennen oder das Eingabebegrenzungszeichen
verwenden.
Beispiel mit Begrenzungszeichendefinition ID=; und DC=,:
WRITE F#ADD (<1 , 2>) F#ADD (<1;2>)
Operanden-Definitionstabelle:
| Operand | Mögliche Struktur | Mögliche Formate | Referenzierung erlaubt | Dynam. Definition | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand
|
C | S | A | G | A | N | P | I | F | B | D | T | L | C | G | O | ja | nein | |
Syntax-Element-Beschreibung:
| Syntax-Element | Beschreibung | |
|---|---|---|
nX
|
Zu überspringende Parameter:
Mit der Ein zu überspringender Parameter muss im |
|
AD=
|
Attribut-Definition:
If |
|
AD=O
|
Nicht änderbar:
Siehe Session-Parameter Anmerkung |
|
AD=M
|
Änderbar:
Siehe Session-Parameter Dies ist die Standardeinstellung. |
|
AD=A
|
Nur zur Eingabe:
Siehe Session-Parameter |
|
|
Anmerkung |
||
Im Beispiel-Programm FUNCEX01
werden die Functions F#ADDITION,
F#CHAR, F#EVEN und F#TEXT verwendet.
Alle Beispiele in diesem Abschnitt werden in der Natural-System-Library SYSEXPG als Quellcode-Objekte und als katalogisierte Objekte zur Verfügung gestellt.
** Example 'FUNCEX01': Function call (Program)
************************************************************************
DEFINE DATA LOCAL
1 #NUM (I2) INIT <5>
1 #A (I2) INIT <1>
1 #B (I2) INIT <2>
1 #C (I2) INIT <3>
1 #CHAR (A1) INIT <'A'>
END-DEFINE
*
IF #NUM = F#ADDITION(<#A,#B,#C>) /* Function with three parameters.
WRITE 'Sum of #A,#B,#C' #NUM
ELSE
IF #NUM = F#ADDITION(<1X,#B,#C>) /* Function with optional parameters.
WRITE 'Sum of #B,#C' #NUM
END-IF
END-IF
*
DECIDE ON FIRST #CHAR
VALUE F#CHAR (<>)(1) /* Function with result array.
WRITE 'Character A found'
VALUE F#CHAR (<>)(2)
WRITE 'Character B found'
NONE
IGNORE
END-DECIDE
*
IF F#EVEN(<#B>) /* Function with logical result value.
WRITE #B 'is an even number'
END-IF
*
F#TEXT(<'Hello', '*'>) /* Function used as a statement.
*
WRITE F#TEXT(<(IR=A12) 'Good'>) /* Function with intermediate result.
*
END
FUNCEX01Sum of #B,#C 5
Character A found
2 is an even number
*** Hello world ***
Good morning
Die Function F#ADDITION ist in der Beispiel-Function FUNCEX02
definiert.
** Example 'FUNCEX02': Function call (Function)
************************************************************************
DEFINE FUNCTION F#ADDITION
RETURNS (I2)
DEFINE DATA PARAMETER
1 #PARM1 (I2) OPTIONAL
1 #PARM2 (I2) OPTIONAL
1 #PARM3 (I2) OPTIONAL
END-DEFINE
/*
RESET F#ADDITION
IF #PARM1 SPECIFIED
F#ADDITION := F#ADDITION + #PARM1
END-IF
IF #PARM2 SPECIFIED
F#ADDITION := F#ADDITION + #PARM2
END-IF
IF #PARM3 SPECIFIED
F#ADDITION := F#ADDITION + #PARM3
END-IF
/*
END-FUNCTION
*
END
Die Function F#CHAR ist in der Beispiel-Function FUNCEX03
definiert.
** Example 'FUNCEX03': Function call (Function) ************************************************************************ DEFINE FUNCTION F#CHAR RETURNS (A1/1:2) /* F#CHAR(1) := 'A' F#CHAR(2) := 'B' /* END-FUNCTION * END
Die Function F#EVEN ist in der Beispiel-Function FUNCEX04
definiert.
** Example 'FUNCEX04': Function call (Function)
************************************************************************
DEFINE FUNCTION F#EVEN
RETURNS (L)
DEFINE DATA
PARAMETER
1 #NUM (N4) BY VALUE
LOCAL
1 #REST (I2)
END-DEFINE
/*
DIVIDE 2 INTO #NUM REMAINDER #REST
/*
IF #REST = 0
F#EVEN := TRUE
ELSE
F#EVEN := FALSE
END-IF
/*
END-FUNCTION
*
END
Die Function F#TEXT ist in der Beispiel-Function FUNCEX05
definiert.
** Example 'FUNCEX05': Function call (Function)
************************************************************************
DEFINE FUNCTION F#TEXT
RETURNS (A20) BY VALUE
DEFINE DATA
PARAMETER
1 #TEXT1 (A5) BY VALUE
1 #TEXT2 (A1) BY VALUE OPTIONAL
LOCAL
1 #FRAME (A3)
END-DEFINE
/*
IF #TEXT2 SPECIFIED
MOVE ALL #TEXT2 TO #FRAME
/*
COMPRESS #FRAME #TEXT1 'world' #FRAME INTO F#TEXT
/*
WRITE F#TEXT
ELSE
COMPRESS #TEXT1 'morning' INTO F#TEXT
/*
END-IF
/*
END-FUNCTION
*
END
Entsprechend der Function-Definition kann ein Function Call ein einzelnes Ergebnisfeld
zurückgeben. Dies kann ein Skalar-Wert sein oder ein Array-Feld, das in dem Statement, in
dem der Function Call eingebettet ist, wie ein temporäres Feld verarbeitet wird. Ist das
Ergebnis ein Array, dann muss unmittelbar nach dem Function Call ein array-index-expression folgen,
mit dem die erforderlichen Ausprägungen adressiert werden.
Zum Beispiel, um auf die erste Ausprägung des zurückgegebenen Array zuzugreifen:
#FCT(<#A,#B>)(1)
Um einen Function Call zur Kompilierungszeit korrekt aufzulösen, benötigt der Kompiler die Format-, Längen- und Array-Struktur der Parameter und des Function-Ergebnisses. Die in dem Function Call angegebenen Parameter werden gegen die entsprechenden Definitionen in der Function geprüft um sicherzustellen, dass sie zueinander passen. Wird eine Function anstelle eines Operanden in einem Statement benutzt, muss das Function-Ergebnis hinsichtlich der Format-, Längen- und Array-Struktur mit dem Operanden übereinstimmen.
Sie haben drei Möglichkeiten, diese Informationen zur Verfügung zu stellen:
Sie können die Parameter- und Ergebnisangaben implizit aus dem katalogisierten Objekt
(falls verfügbar) der aufgerufenen Funktion gewinnen, wenn zuvor kein DEFINE
PROTOTYPE-Statement ausgeführt wurde.
Dieses Verfahren erfordert den geringsten Programmieraufwand.
Sie können ein DEFINE
PROTOTYPE-Statement benutzen. Ein DEFINE
PROTOTYPE-Statement müssen Sie benutzen, wenn das katalogisierte Objekt der
aufgerufenen Function nicht verfügbar ist oder wenn die Function zur Kompilierungszeit
nicht bekannt, d.h., anstelle eines Function-Namens wird der Name einer
alphanumerischen Variablen im Function Call angegeben.
Sie können eine explizite (IR=)-Klausel im Function Call angeben.
Bei den ersten beiden Möglichkeiten erfolgt eine vollständige Validierung der Format-, Längen- und Array-Struktur der Parameter und des Function-Ergebnisses.
Wenn weder ein DEFINE PROTOTYPE-Statement noch ein katalogisiertes
Function-Objekt existiert, können Sie die folgenden Klauseln in Ihrem Function Call
benutzen:
Die Klausel (IR=) gibt die Format-, Längen- und Array-Struktur des
Funktionsergebnisses an.
Diese Klausel bestimmt, welche Format-, Längen- und Array-Struktur der Kompiler für
das Ergebnisfeld (das Zwischenergebnis, so wie es von dem Statement benutzt wird,
das den Function Call enthält) nehmen soll. Wenn für einen Function Call eine
Prototyp-Definition zur Verfügung steht, dann setzt die Klausel (IR=) die
Angaben in dem Prototyp außer Kraft.
Die Klausel (IR=) erzwingt keine Parameterprüfungen.
Die Klausel (PT=) benutzt einen zuvor definierten Prototyp, dessen
Namen anders lautet als der Name der Function. Diese Klausel validiert die Parameter
und das Ergebnis der Function mit Hilfe eines DEFINE
PROTOTYPE-Statement mit dem referenzierten Namen.
In dem folgenden Beispiel wird die Function #MULT aufgerufen, es
gelten jedoch die Parameter- und Ergebnisangaben aus dem Prototyp, dessen Name
#ADD ist:
#I := #MULT(<(PT=#ADD) 2 , 3>)
Zur Prüfung der Parameter wird die zuerst gefundene der nachfolgend aufgeführten Definitionen verwendet:
die Prototyp-Definition, die in der (PT=)-Klausel referenziert wird;
die Prototyp-Definition im DEFINE
PROTOTYPE-Statement, deren Namen mit dem Namen der Function
übereinstimmt, der im Function Call benutzt wird;
die Parameterangaben im katalogisierten Function-Objekt, die mit dem DEFINE
FUNCTION-Statement geliefert werden.
Falls keine dieser Optionen angegeben ist, wird keine Parameter-Validierung durchgeführt. Das gestattet es, im Function Call eine beliebige Anzahl Parameter mit beliebigem Layout zu mitliefern, ohne einen Syntaxfehler zu erhalten.
Zur Prüfung des Ergebnisses der Function wird die zuerst gefundene der nachfolgend aufgeführten Definitionen verwendet:
die Definition, die in der (IR=)-Klausel zur Verfügung gestellt wird;
die RETURNS-Definition im Pprototyp, die in der (PT=)-Klausel
referenziert wird;
die Prototyp-Definition im DEFINE PROTOTYPE-Statement, bei der der
Prototyp-Namen mit dem Namen der Function übereinstimmt, der im Function Call
benutzt wird;
die Angabe des Function-Ergebnisses in dem katalogisierten Function-Objekt.
Falls keine der aufgeführten Definitionen angegeben ist, wird ein Syntaxfehler ausgegeben.
Programm:
** Example 'FUNCBX01': Declare result value and parameters (Program)
************************************************************************
*
DEFINE DATA LOCAL
1 #PROTO-NAME (A20)
1 #PARM1 (I4)
1 #PARM2 (I4)
END-DEFINE
*
DEFINE PROTOTYPE VARIABLE #PROTO-NAME
RETURNS (I4)
DEFINE DATA PARAMETER
1 #P1 (I4) BY VALUE OPTIONAL
1 #P2 (I4) BY VALUE
END-DEFINE
END-PROTOTYPE
*
#PROTO-NAME := 'F#MULTI'
#PARM1 := 3
#PARM2 := 5
*
WRITE #PROTO-NAME(<#PARM1, #PARM2>)
WRITE #PROTO-NAME(<1X ,5>)
*
WRITE F#MULTI(<(PT=#PROTO-NAME) #PARM1,#PARM2>)
*
WRITE F#MULTI(<(IR=N20) #PARM1, #PARM2>)
*
END
Function F#MULTI:
** Example 'FUNCBX02': Declare result value and parameters (Function)
************************************************************************
DEFINE FUNCTION F#MULTI
RETURNS #RESULT (I4) BY VALUE
DEFINE DATA PARAMETER
1 #FACTOR1 (I4) BY VALUE OPTIONAL
1 #FACTOR2 (I4) BY VALUE
END-DEFINE
/*
IF #FACTOR1 SPECIFIED
#RESULT := #FACTOR1 * #FACTOR2
ELSE
#RESULT := #FACTOR2 * 10
END-IF
/*
END-FUNCTION
*
END
Alle Function Calls, die in einem Natural-Statement verwendet werden, werden ausgewertet, bevor mit der Ausführung des Statements begonnen wird. Sie werden in derselben Reihenfolge ausgeführt, in der sie im Statement erscheinen. Die Function-Ergebniswerte werden in temporären Feldern gespeichert, die später als Operanden bei der Statement-Ausführung verwendet werden.
Das Aufrufen einer Function, die änderbare Parameter hat, die wiederholt innerhalb desselben Statements benutzt werden, kann unterschiedliche Function-Ergebnisse verursachen, wie im folgenden Beispiel gezeigt wird:
Bevor die Ausführung des COMPUTE-Statement beginnt, hat die Variable
#I den Wert 1. Im ersten Schritt wird die Funktion
F#RETURN ausgeführt. Dadurch ändert sich #I auf den Wert
2 und gibt den Wert 2 als das Ergebnis der Funktion zurück.
Danach wird mit der COMPUTE-Operation begonnen, wobei die erhöhte Variable
#I (2) und das temporäre Feld (2) auf die Summe von
4 addiert werden.
** Example 'FUNCCX01': Parameter changed within function (Program)
************************************************************************
DEFINE DATA LOCAL
1 #I (I2) INIT <1>
1 #RESULT (I2)
END-DEFINE
*
COMPUTE #RESULT := #I + F#RETURN(<#I>) /* First evaluate function call,
/* then execute the addition.
*
WRITE '#I :' #I /
'#RESULT:' #RESULT
*
END
** Example 'FUNCCX02': Parameter changed within function (Function)
************************************************************************
DEFINE FUNCTION F#RETURN
RETURNS #RESULT (I2) BY VALUE
DEFINE DATA PARAMETER
1 #PARM1 (I2) BY VALUE RESULT
END-DEFINE
/*
#PARM1 := #PARM1 + 1 /* Increment parameter.
#RESULT := #PARM1 /* Set result value.
/*
END-FUNCTION
*
END
FUNCCX01:
#I : 2 #RESULT: 4
Sie können einen Function Call kann auch anstelle eines Natural-Statements benutzen, d.h. ohne den Function Call in ein anderes Statement einzubetten. In diesem Fall braucht der Function Call keinen Ergebniswert zurückzuliefern; falls doch, wird der Ergebniswert ignoriert.
Um eine unerwünschte Verknüpfung zu dem vorangehenden Statement zu verhindern, muss ein
Semikolon (;) gesetzt werden, um den Function Call ausdrücklich von diesem
Statement zu trennen.
Programm:
** Example 'FUNCDX01': Using a function as a statement (Program)
************************************************************************
DEFINE DATA LOCAL
1 #A (I4) INIT <1>
1 #B (I4) INIT <2>
END-DEFINE
*
*
WRITE 'Write:' #A #B
F#PRINT-ADD(< 2,3 >) /* Function call belongs to operand list
/* immediately preceding it.
*
WRITE // '*************************' //
*
WRITE 'Write:' #A #B; /* Semicolon separates operands and function.
F#PRINT-ADD(< 2,3 >) /* Function call does not belong to the
/* operand list.
*
END
Function:
** Example 'FUNCDX02': Using a function as a statement (Function)
************************************************************************
DEFINE FUNCTION F#PRINT-ADD
RETURNS (I4)
DEFINE DATA PARAMETER
1 #SUMMAND1 (I4) BY VALUE
1 #SUMMAND2 (I4) BY VALUE
END-DEFINE
/*
F#PRINT-ADD := #SUMMAND1 + #SUMMAND2 /* Result of function call.
WRITE 'Function call:' F#PRINT-ADD
/*
END-FUNCTION
*
END
Ausgabe des Programms FUNCDX01:
Function call: 5 Write: 1 2 5 ************************* Write: 1 2 Function call: 5