[resulttype] funcname ( parameterlist ) := FUNCTION
code
RETURN retval;
END;
The FUNCTION structure allows you to pass parameters to a set of related attribute definitions. This makes it possible to pass parameters to an attribute that is defined in terms of other non-exported attributes without the need to parameterise all of those as well.
Side-effect actions contained in the code of the FUNCTION must have definition names that must be referenced by the WHEN function to execute.
Example:
EXPORT doProjectChild(parentRecord l,UNSIGNED idAdjust2) := FUNCTION newChildRecord copyChild(childRecord l) := TRANSFORM SELF.person_id := l.person_id + idAdjust2; SELF := l; END; RETURN PROJECT(CHOOSEN(l.children, numChildren),copyChild(LEFT)); END; //And called from SELF.children := doProjectChild(l, 99); //********************************** EXPORT isAnyRateGE(STRING1 rate) := FUNCTION SetValidRates := ['0','1','2','3','4','5','6','7','8','9']; IsValidTradeRate := ValidDate(Trades.trd_drpt) AND Trades.trd_rate >= rate AND Trades.trd_rate IN SetValidRates; ValidPHR := Prev_rate(phr_grid_flag = TRUE, phr_rate IN SetValidRates, ValidDate(phr_date)); IsPHRGridRate := EXISTS(ValidPHR(phr_rate >= rate, AgeOf(phr_date)<=24)); IsMaxPHRRate := MAX(ValidPHR(AgeOf(phr_date) > 24), Prev_rate.phr_rate) >= rate; RETURN IsValidTradeRate OR IsPHRGridRate OR IsMaxPHRRate; END; //************************************************************* //a FUNCTION with side-effect Action namesTable := FUNCTION namesRecord := RECORD STRING20 surname; STRING10 forename; INTEGER2 age := 25; END; o := OUTPUT('namesTable used by user <x>'); ds := DATASET([{'x','y',22}],namesRecord); RETURN WHEN(ds,O); END; z := namesTable : PERSIST('z'); //the PERSIST causes the side-effect action to execute only when the PERSIST is re-built OUTPUT(z); //************************************************************* //a coordinated set of 3 examples NameRec := RECORD STRING5 title; STRING20 fname; STRING20 mname; STRING20 lname; STRING5 name_suffix; STRING3 name_score; END; MyRecord := RECORD UNSIGNED id; STRING uncleanedName; NameRec Name; END; ds := DATASET('RTTEST::RowFunctionData', MyRecord, THOR); STRING73 CleanPerson73(STRING inputName) := FUNCTION suffix :=[ ' 0',' 1',' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9', ' J',' JR',' S',' SR']; InWords := Std.Str.CleanSpaces(inputName); HasSuffix := InWords[LENGTH(TRIM(InWords))-1 ..] IN suffix; WordCount := LENGTH(TRIM(InWords,LEFT,RIGHT)) - LENGTH(TRIM(InWords,ALL)) + 1; HasMiddle := WordCount = 5 OR (WordCount = 4 AND NOT HasSuffix) ; Sp1 := Std.Str.Find(InWords,' ',1); Sp2 := Std.Str.Find(InWords,' ',2); Sp3 := Std.Str.Find(InWords,' ',3); Sp4 := Std.Str.Find(InWords,' ',4); STRING5 title := InWords[1..Sp1-1]; STRING20 fname := InWords[Sp1+1..Sp2-1]; STRING20 mname := IF(HasMiddle,InWords[Sp2+1..Sp3-1],''); STRING20 lname := MAP(HasMiddle AND NOT HasSuffix => InWords[Sp3+1..], HasMiddle AND HasSuffix => InWords[Sp3+1..Sp4-1], NOT HasMiddle AND NOT HasSuffix => InWords[Sp2+1..], NOT HasMiddle AND HasSuffix => InWords[Sp2+1..Sp3-1], ''); STRING5 name_suffix := IF(HasSuffix,InWords[LENGTH(TRIM(InWords))-1..],''); STRING3 name_score := ''; RETURN title + fname + mname + lname + name_suffix + name_score; END; //Example 1 - a transform to create a row from an uncleaned name NameRec createRow(string inputName) := TRANSFORM cleanedText := LocalAddrCleanLib.CleanPerson73(inputName); SELF.title := cleanedText[1..5]; SELF.fname := cleanedText[6..25]; SELF.mname := cleanedText[26..45]; SELF.lname := cleanedText[46..65]; SELF.name_suffix := cleanedText[66..70]; SELF.name_score := cleanedText[71..73]; END; myRecord t(myRecord l) := TRANSFORM SELF.Name := ROW(createRow(l.uncleanedName)); SELF := l; END; y := PROJECT(ds, t(LEFT)); OUTPUT(y); //Example 2 - an attribute using that transform to generate the row. NameRec cleanedName(STRING inputName) := ROW(createRow(inputName)); myRecord t2(myRecord l) := TRANSFORM SELF.Name := cleanedName(l.uncleanedName); SELF := l; END; y2 := PROJECT(ds, t2(LEFT)); OUTPUT(y2); //Example 3 = Encapsulate the transform inside the attribute by // defining a FUNCTION. NameRec cleanedName2(STRING inputName) := FUNCTION NameRec createRow := TRANSFORM cleanedText := LocalAddrCleanLib.CleanPerson73(inputName); SELF.title := cleanedText[1..5]; SELF.fname := cleanedText[6..25]; SELF.mname := cleanedText[26..45]; SELF.lname := cleanedText[46..65]; SELF.name_suffix := cleanedText[66..70]; SELF.name_score := cleanedText[71..73]; END; RETURN ROW(createRow); END; myRecord t3(myRecord l) := TRANSFORM SELF.Name := cleanedName2(l.uncleanedName); SELF := l; END; y3 := PROJECT(ds, t3(LEFT)); OUTPUT(y3); //Example using MODULE structure to return multiple values from a FUNCTION OperateOnNumbers(Number1, Number2) := FUNCTION result := MODULE EXPORT Multiplied := Number1 * Number2; EXPORT Differenced := Number1 - Number2; EXPORT Summed := Number1 + Number2; END; RETURN result; END; OperateOnNumbers(23,22).Multiplied; OperateOnNumbers(23,22).Differenced; OperateOnNumbers(23,22).Summed;
See Also: MODULE Structure, TRANSFORM Structure, WHEN