खोज…
परिचय
प्रगति एबीएल में एक उपयोगकर्ता परिभाषित कार्य एक पुन: प्रयोज्य कार्यक्रम मॉड्यूल है।
टिप्पणियों
- एक फ़ंक्शन को "मुख्य" प्रक्रिया में घोषित किया जाना चाहिए। इसे एक प्रक्रिया के अंदर या किसी अन्य फ़ंक्शन के अंदर घोषित नहीं किया जा सकता है।
- प्रोग्रेस एबीएल में एक फ़ंक्शन हैस्केल या जावास्क्रिप्ट जैसी प्रोग्रामिंग भाषाओं के विपरीत "प्रथम श्रेणी का नागरिक" नहीं है। आप एक फ़ंक्शन को इनपुट या आउटपुट पैरामीटर के रूप में पारित नहीं कर सकते। हालाँकि आप
DYNAMIC-FUNCTION
याCALL
ऑब्जेक्ट का उपयोग करकेDYNAMIC-FUNCTION
रूप से उनका उपयोग कर सकते हैं। - आपके प्रश्नों को कॉल करने से सूचकांक के खराब होने के कारण खराब प्रदर्शन हो सकता है। फ़ंक्शन के मान को किसी चर में निर्दिष्ट करने का प्रयास करें और उस चर का उपयोग
WHERE
-clause में करें।
साधारण कार्य
/* 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.
अग्रेषण कार्यों की घोषणा
एक फ़ंक्शन को आगे घोषित किया जा सकता है, यह सी हेडर फ़ाइल में विनिर्देशों के समान है। इस तरह से संकलक जानता है कि एक फ़ंक्शन को बाद में उपलब्ध कराया जाएगा।
आगे की घोषणाओं के बिना फ़ंक्शन को कोड में कॉल करने से पहले घोषित किया जाना चाहिए। आगे की घोषणा में FUNCTION
स्पेसिफिकेशन (फ़ंक्शन नाम, रिटर्न टाइप और पैरामीटर डेटा प्रकार और ऑर्डर) शामिल हैं। यदि आगे की घोषणा वास्तविक कार्य से मेल नहीं खाती है तो संकलक त्रुटियों का उत्पादन करेगा और कोड चलाने में विफल हो जाएगा।
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.
मल्टीपल रिटर्न स्टेटमेंट (लेकिन सिंगल रिटर्न वैल्यू)
एक फ़ंक्शन में कई रिटर्न स्टेटमेंट हो सकते हैं और उन्हें वास्तविक फ़ंक्शन के विभिन्न भागों में रखा जा सकता है। वे सभी को एक ही डेटा प्रकार को वापस करने की आवश्यकता है, हालांकि।
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
-object का उपयोग करके आप गतिशील रूप से फ़ंक्शन को 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
ऑब्जेक्ट डायनामिक-फंक्शन के जितना हल्का नहीं है। इसका उपयोग विभिन्न चीजों को कॉल करने के लिए किया जा सकता है: फ़ंक्शंस, प्रक्रियाएं, बाहरी कार्यक्रम, विंडोज डीएलएल-फ़ंक्शंस। यह ऑब्जेक्ट्स और एक्सेस गेटर्स / सेटर पर तरीकों को भी लागू कर सकता है।
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.