수색…
소개
Progress ABL의 사용자 정의 함수는 재사용 가능한 프로그램 모듈입니다.
비고
- 함수는 "main"프로 시저에서 선언되어야합니다. 프로 시저 내부 또는 다른 함수 내에서 선언 할 수 없습니다.
- Progress ABL의 함수는 Haskell이나 Javascript 같은 프로그래밍 언어와 달리 "일류 시민"이 아닙니다. 함수를 입력 또는 출력 매개 변수로 전달할 수 없습니다. 그러나
DYNAMIC-FUNCTION
또는CALL
오브젝트를 사용하여DYNAMIC-FUNCTION
으로 호출 할 수 있습니다. - 쿼리에서 함수를 호출하면 인덱스 일치가 손상되어 성능이 저하 될 수 있습니다. 함수의 값을 변수에 할당하고 대신
WHERE
해당 변수를 사용하십시오.
단순 기능
/* This function returns TRUE if input is the letter "b" and false otherwise */
FUNCTION isTheLetterB RETURNS LOGICAL (INPUT pcString AS CHARACTER):
IF pcString = "B" THEN
RETURN TRUE.
ELSE
RETURN FALSE.
END FUNCTION.
/* Calling the function with "b" as input - TRUE expected */
DISPLAY isTheLetterB("b").
/* Calling the function with "r" as input - FALSE expected */
DISPLAY isTheLetterB("r").
구문의 일부는 실제로 필요하지 않습니다.
/* RETURNS isn't required, INPUT isn't required on INPUT-parameters */
FUNCTION isTheLetterB LOGICAL (pcString AS CHARACTER):
IF pcString = "B" THEN
RETURN TRUE.
ELSE
RETURN FALSE.
/* END FUNCTION can be replaced with END */
END.
전달 함수 선언
함수는 앞으로 선언 될 수 있습니다. 이것은 C 헤더 파일의 스펙과 유사합니다. 그런 식으로 컴파일러는 나중에 함수를 사용할 수 있음을 알고 있습니다.
forward 선언이 없으면 함수는 코드에서 호출되기 전에 반드시 선언되어야한다. 전방 선언은 FUNCTION
스펙 (함수 이름, 리턴 유형 및 매개 변수 데이터 유형 및 순서)으로 구성됩니다. forward 선언이 실제 함수와 일치하지 않으면 컴파일러에서 오류가 발생하고 코드가 실행되지 않습니다.
FUNCTION dividableByThree LOGICAL (piNumber AS INTEGER) FORWARD.
DISPLAY dividableByThree(9).
FUNCTION dividableByThree LOGICAL (piNumber AS INTEGER):
IF piNumber MODULO 3 = 0 THEN
RETURN TRUE.
ELSE
RETURN FALSE.
END.
다중 입력 매개 변수
/ * 이렇게하면 "HELLO WORLD"라는 메시지 상자가 나타납니다 * /
FUNCTION cat RETURNS CHARACTER ( c AS CHARACTER, d AS CHARACTER):
RETURN c + " " + d.
END.
MESSAGE cat("HELLO", "WORLD") VIEW-AS ALERT-BOX.
여러 개의 return 문 (단 하나의 반환 값)
함수는 여러 개의 return 문을 가질 수 있으며 실제 함수의 다른 부분에 배치 될 수 있습니다. 그들은 모두 동일한 데이터 유형을 반환해야합니다.
FUNCTION returning DATE ( dat AS DATE):
IF dat < TODAY THEN DO:
DISPLAY "<".
RETURN dat - 200.
END.
ELSE DO:
DISPLAY ">".
RETURN TODAY.
END.
END.
MESSAGE returning(TODAY + RANDOM(-50, 50)) VIEW-AS ALERT-BOX.
함수는 실제로 아무것도 반환하지 않아도됩니다. 그러면 반환 값은 무엇입니까? (알 수 없는). 컴파일러는 이것을 잡지 않습니다 (하지만 동료는 피할 것입니다).
/* This function will only return TRUE or ?, never FALSE, so it might lead to troubles */
FUNCTION inTheFuture LOGICAL ( dat AS DATE):
IF dat > TODAY THEN DO:
RETURN TRUE.
END.
END.
MESSAGE inTheFuture(TODAY + RANDOM(-50, 50)) VIEW-AS ALERT-BOX.
출력 및 입출력 매개 변수
함수는 단일 값만 반환 할 수 있지만 한 가지 방법이 있습니다. 매개 변수는 입력 매개 변수로 제한되지 않습니다. INPUT
, OUTPUT
및 INPUT-OUTPUT
매개 변수를 선언 할 수 있습니다.
INPUT
매개 변수와 달리 매개 변수 앞에 OUTPUT
또는 INPUT-OUTPUT
지정해야합니다.
일부 코딩 규칙은 이와 같지 않을 수도 있지만 수행 할 수 있습니다.
/* Function will add numbers and return a sum (AddSomSumbers(6) = 6 + 5 + 4 + 3 + 2 + 1 = 21 */
/* It will also have a 1% per iteration of failing */
/* To handle that possibility we will have a status output parameter */
FUNCTION AddSomeNumbers INTEGER ( INPUT number AS INTEGER, OUTPUT procstatus AS CHARACTER):
procStatus = "processing".
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE n AS INTEGER NO-UNDO.
/* Iterate number times */
DO i = 1 TO number:
/* Do something */
n = n + i.
/* Fake a 1% chance for an error that breaks the function */
IF RANDOM(1,100) = 1 THEN
RETURN 0.
END.
procStatus = "done".
RETURN n.
END.
DEFINE VARIABLE ret AS INTEGER NO-UNDO.
DEFINE VARIABLE stat AS CHARACTER NO-UNDO.
/* Call the function */
ret = AddSomeNumbers(30, OUTPUT stat).
/* If "stat" is done we made it! */
IF stat = "done" THEN DO:
MESSAGE "We did it! Sum:" ret VIEW-AS ALERT-BOX.
END.
ELSE DO:
MESSAGE "An error occured" VIEW-AS ALERT-BOX ERROR.
END.
다음은 INPUT-OUTPUT
매개 변수의 예입니다.
/* Function doubles a string and returns the length of the new string */
FUNCTION doubleString RETURN INTEGER (INPUT-OUTPUT str AS CHARACTER).
str = str + str.
RETURN LENGTH(str).
END.
DEFINE VARIABLE str AS CHARACTER NO-UNDO.
DEFINE VARIABLE len AS INTEGER NO-UNDO.
str = "HELLO".
len = doubleString(INPUT-OUTPUT str).
MESSAGE
"New string: " str SKIP
"Length: " len VIEW-AS ALERT-BOX.
재귀
재귀 참조
함수는 스스로를 호출 할 수 있기 때문에 반복적으로 호출 할 수 있습니다.
FUNCTION factorial INTEGER (num AS INTEGER).
IF num = 1 THEN
RETURN 1.
ELSE
RETURN num * factorial(num - 1).
END FUNCTION.
DISPLAY factorial(5).
표준 설정 (시작 매개 변수)에서는 진행 세션이이 예제에서 매우 큰 숫자를 처리하지 못합니다. factorial(200)
이 스택을 채우고 오류가 발생합니다.
함수의 동적 호출
DYNAMIC-FUNCTION
또는 CALL
개체를 사용하면 동적으로 함수를 호출 할 수 있습니다.
DEFINE VARIABLE posY AS INTEGER NO-UNDO.
DEFINE VARIABLE posX AS INTEGER NO-UNDO.
DEFINE VARIABLE OKkeys AS CHARACTER NO-UNDO INIT "QLDRUS".
DEFINE VARIABLE Step AS INTEGER NO-UNDO INIT 1.
DEFINE VARIABLE moved AS LOGICAL NO-UNDO.
/* Set original position */
posY = 10.
posX = 10.
/* Move up (y coordinates - steps ) */
FUNCTION moveU LOGICAL (INPUT steps AS INTEGER):
IF posY = 0 THEN
RETURN FALSE.
posY = posY - steps.
IF posY < 0 THEN
posY = 0.
RETURN TRUE.
END FUNCTION.
/* Move down (y coordinates + steps ) */
FUNCTION moveD LOGICAL (INPUT steps AS INTEGER):
IF posY = 20 THEN
RETURN FALSE.
posY = posY + steps.
IF posY > 20 THEN
posY = 20.
END FUNCTION.
/* Move left (x coordinates - steps ) */
FUNCTION moveL LOGICAL (INPUT steps AS INTEGER):
IF posX = 0 THEN
RETURN FALSE.
posX = posX - steps.
IF posX < 0 THEN
posX = 0.
RETURN TRUE.
END FUNCTION.
/* Move down (x coordinates + steps ) */
FUNCTION moveR LOGICAL (INPUT steps AS INTEGER):
IF posX = 20 THEN
RETURN FALSE.
posX = posX + steps.
IF posX > 20 THEN
posX = 20.
END FUNCTION.
REPEAT:
DISPLAY posX posY step WITH FRAME x1 1 DOWN.
READKEY.
IF INDEX(OKKeys, CHR(LASTKEY)) <> 0 THEN DO:
IF CHR(LASTKEY) = "q" THEN LEAVE.
IF CAPS(CHR(LASTKEY)) = "s" THEN UPDATE step WITH FRAME x1.
ELSE DO:
moved = DYNAMIC-FUNCTION("move" + CAPS(CHR(LASTKEY)), INPUT step).
IF moved = FALSE THEN
MESSAGE "Out of bounds".
END.
END.
END.
CALL
오브젝트는 DYNAMIC-FUNCTION만큼 가볍지 않습니다. 함수, 프로 시저, 외부 프로그램, Windows DLL 함수 등 여러 가지를 호출하는 데 사용할 수 있습니다. 또한 객체에 대한 메소드를 호출하고 getter / setter에 액세스 할 수 있습니다.
DEFINE VARIABLE functionHandle AS HANDLE NO-UNDO.
DEFINE VARIABLE returnvalue AS CHARACTER NO-UNDO.
FUNCTION isPalindrome LOGICAL (INPUT txt AS CHARACTER, OUTPUT txtBackwards AS CHARACTER):
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DO i = LENGTH(txt) TO 1 BY -1:
txtBackwards = txtBackwards + SUBSTRING(txt, i, 1).
END.
IF txt = txtBackwards THEN
RETURN TRUE.
ELSE
RETURN FALSE.
END FUNCTION.
CREATE CALL functionHandle.
functionHandle:CALL-NAME = "isPalindrome".
/* Sets CALL-TYPE to the default */
functionHandle:CALL-TYPE = FUNCTION-CALL-TYPE.
functionHandle:NUM-PARAMETERS = 2.
functionHandle:SET-PARAMETER(1, "CHARACTER", "INPUT", "HELLO WORLD").
functionHandle:SET-PARAMETER(2, "CHARACTER", "OUTPUT", returnvalue).
functionHandle:INVOKE.
MESSAGE "Text backwards: " returnvalue "Is it a palindrome? " functionHandle:RETURN-VALUE VIEW-AS ALERT-BOX.
DELETE OBJECT functionHandle.
CREATE CALL functionHandle.
functionHandle:CALL-NAME = "isPalindrome".
/* Sets CALL-TYPE to the default */
functionHandle:CALL-TYPE = FUNCTION-CALL-TYPE.
functionHandle:NUM-PARAMETERS = 2.
functionHandle:SET-PARAMETER(1, "CHARACTER", "INPUT", "ANNA").
functionHandle:SET-PARAMETER(2, "CHARACTER", "OUTPUT", returnvalue).
functionHandle:INVOKE.
MESSAGE "Text backwards: " returnvalue "Is it a palindrome? " functionHandle:RETURN-VALUE VIEW-AS ALERT-BOX.
DELETE OBJECT functionHandle.