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
Dieses Dokument 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-Ergenis-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
FUNCEX01
Sum 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