Skip to content

Commit

Permalink
Merge pull request #17623 from JamesDeFabia/HPCC-29993FunctionModuleE…
Browse files Browse the repository at this point in the history
…xamples

HPCC-29993 Fix FUNCTION and MODULE doc examples so they can run

Reviewed-By: Richard Taylor <[email protected]>
Merged-by: Gavin Halliday <[email protected]>
  • Loading branch information
ghalliday authored Aug 3, 2023
2 parents cdc2085 + 6d579f5 commit 3ebb71a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 91 deletions.
104 changes: 40 additions & 64 deletions docs/EN_US/ECLLanguageReference/ECLR_mods/SpecStruc-FuncTion.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,69 +88,27 @@

<para>Example:</para>

<programlisting lang="ECL">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 &gt;= 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 &gt;= rate,
AgeOf(phr_date)&lt;=24));
IsMaxPHRRate := MAX(ValidPHR(AgeOf(phr_date) &gt; 24),
Prev_rate.phr_rate) &gt;= 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 &lt;x&gt;');
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

<programlisting lang="ECL" role="runnable">//a coordinated set of 3 examples
IMPORT Std;
NameRec := RECORD
STRING5 title;
STRING20 fname;
STRING20 mname;
STRING20 lname;
STRING5 name_suffix;
STRING3 name_score;
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);
ds := DATASET([{1,'Mr. John Smith JR'},
{2,'Mrs. Susie Samantha Jones 3'},
{3,'Dr. Fred Taylor SR'}],MyRecord);

STRING73 CleanPerson73(STRING inputName) := FUNCTION
suffix :=[ ' 0',' 1',' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9',
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;
Expand All @@ -175,8 +133,8 @@ STRING73 CleanPerson73(STRING inputName) := FUNCTION
END;

//Example 1 - a transform to create a row from an uncleaned name
NameRec createRow(string inputName) := TRANSFORM
cleanedText := LocalAddrCleanLib.CleanPerson73(inputName);
NameRec createRow(STRING inputName) := TRANSFORM
cleanedText := CleanPerson73(inputName);
SELF.title := cleanedText[1..5];
SELF.fname := cleanedText[6..25];
SELF.mname := cleanedText[26..45];
Expand All @@ -203,9 +161,9 @@ 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);
cleanedText := CleanPerson73(inputName);
SELF.title := cleanedText[1..5];
SELF.fname := cleanedText[6..25];
SELF.mname := cleanedText[26..45];
Expand All @@ -223,21 +181,39 @@ myRecord t3(myRecord l) := TRANSFORM
END;

y3 := PROJECT(ds, t3(LEFT));
OUTPUT(y3);
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;
EXPORT Summed := Number1 + Number2;
END;
RETURN result;
END;

OperateOnNumbers(23,22).Multiplied;
OperateOnNumbers(23,22).Differenced;
OperateOnNumbers(23,22).Summed; </programlisting>
OUTPUT(OperateOnNumbers(23,22).Multiplied); //506
OUTPUT(OperateOnNumbers(23,22).Differenced); //1
OUTPUT(OperateOnNumbers(23,22).Summed); //45

//*************************************************************
//a FUNCTION with side-effect Action
namesTable := FUNCTION
namesRecord := RECORD
STRING20 surname;
STRING10 forename;
INTEGER2 age := 25;
END;
o := OUTPUT('namesTable used by user &lt;x&gt;');
ds1 := DATASET([{'x','y',22}],namesRecord);
RETURN WHEN(ds1,o);
END;
z := namesTable : PERSIST('z');
//the PERSIST causes the side-effect action to execute only when the PERSIST is re-built
OUTPUT(z);
</programlisting>

<para>See Also: <link linkend="MODULE_Structure">MODULE Structure</link>,
<link linkend="TRANSFORM_Structure">TRANSFORM Structure</link>, <link
Expand Down
60 changes: 33 additions & 27 deletions docs/EN_US/ECLLanguageReference/ECLR_mods/SpecStruc-Module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,10 @@
the EXPORT MyModuleStructure MODULE structure is contained in an ECL
Repository module named MyModule and that it contains an EXPORT
<emphasis>member</emphasis> named MyDefinition, you would reference that
<emphasis>definition</emphasis> as:</para>
<emphasis>definition</emphasis> as
MyModule.MyModuleStructure.MyDefinition:</para>

<para><programlisting lang="ECL" role="runnable">//MyModule.MyModuleStructure.MyDefinition

MyMod := MODULE
<para><programlisting lang="ECL" role="runnable">MyMod := MODULE
SHARED x := 88;
y := 42;
EXPORT InMod := MODULE //nested MODULE
Expand Down Expand Up @@ -290,55 +289,62 @@ IF (doIt, OUTPUT(customerNames.File));

<para>Example:</para>

<programlisting lang="ECL">EXPORT filterDataset(STRING search, BOOLEAN onlyOldies) := MODULE
<programlisting lang="ECL" role="runnable">namesRecord := RECORD
STRING20 surname;
STRING10 forename;
INTEGER2 age := 25;
END;
namesTable := DATASET([{'Smith','Sue',72},
{'Jones','Joe',32},
{'Jones','Fred',82}],namesRecord);

filterDataset1(STRING search, BOOLEAN onlyOldies) := MODULE
f := namesTable; //local to the "g" definition
SHARED g := IF (onlyOldies, f(age &gt;= 65), f);
//SHARED = visible only within the structure
EXPORT included := g(surname != search);
EXPORT excluded := g(surname = search);
EXPORT included := g(surname = search);
EXPORT excluded := g(surname &lt;&gt; search);
//EXPORT = visible outside the structure
END;
filtered := filterDataset('Halliday', TRUE);
OUTPUT(filtered.included,,NAMED('Included'));
OUTPUT(filtered.excluded,,NAMED('Excluded'));
filtered1 := filterDataset1('Smith', TRUE);
OUTPUT(filtered1.included,,NAMED('Included1'));
OUTPUT(filtered1.excluded,,NAMED('Excluded1'));

//same result, different coding style:
EXPORT filterDataset(BOOLEAN onlyOldies) := MODULE
filterDataset2(BOOLEAN onlyOldies) := MODULE
f := namesTable;
SHARED g := IF (onlyOldies, f(age &gt;= 65), f);
EXPORT included(STRING search) := g(surname &lt;&gt; search);
EXPORT excluded(STRING search) := g(surname = search);
EXPORT included(STRING search) := g(surname = search);
EXPORT excluded(STRING search) := g(surname &lt;&gt; search);
END;
filtered := filterDataset(TRUE);
OUTPUT(filtered.included('Halliday'),,NAMED('Included'));
OUTPUT(filterDataset(true).excluded('Halliday'),,NAMED('Excluded'));


filtered2 := filterDataset2(TRUE);
OUTPUT(filtered2.included('Smith'),,NAMED('Included2'));
OUTPUT(filterDataset2(true).excluded('Smith'),,NAMED('Excluded2'));

//VIRTUAL examples
Mod1 := MODULE,VIRTUAL //a fully abstract module
EXPORT val := 1;
EXPORT func(INTEGER sc) := val * sc;
END;

Mod2 := MODULE(Mod1) //instance
EXPORT val := 3; //a concete member, overriding default value
//while func remains abstract
EXPORT val := 3; //a concete member, overriding default value
//while func remains abstract
END;

Mod3 := MODULE(Mod1) //a fully concete instance
EXPORT func(INTEGER sc) := val + sc; //overrides inherited func
END;
OUTPUT(Mod2.func(5)); //result is 15
OUTPUT(Mod3.func(5)); //result is 6

//FORWARD example
EXPORT MyModule := MODULE, FORWARD
EXPORT INTEGER foo := bar;
MyModule := MODULE, FORWARD
EXPORT INTEGER foo := bar; //forward reference
EXPORT INTEGER bar := 42;
END;

MyModule.foo;

OUTPUT(MyModule.foo);
</programlisting>

<para>See Also: <link linkend="FUNCTION_Structure">FUNCTION
Expand Down

0 comments on commit 3ebb71a

Please sign in to comment.