One of my new colleagues has been reading these posts whilst he is learning to program in 2E.
This part is a collection of some general tips in 2E around Format Relations, Function Options, Function Wrapping and Sharing Subroutines.
As always, any comments good and bad are welcomed as are requests for subject matter.
Format Relations Considerations
For certain function types relations can be dropped (PMTRCD and PRTFIL). This is useful to make your functions as efficient as possible.
For other functions you will generally have the option to influence the amount of default code and functionality that will be generated by the 2E code generators by detailing the level of referential integrity you wish the function to have.
Careful consideration should be given to setting the format relations to the desired level. These are MANDATORY, OPTIONAL, USER, NO ERROR and of course, DROPPED. I fully recommend the best practice of RTFM.
Function Options
This part is a collection of some general tips in 2E around Format Relations, Function Options, Function Wrapping and Sharing Subroutines.
As always, any comments good and bad are welcomed as are requests for subject matter.
Format Relations Considerations
For certain function types relations can be dropped (PMTRCD and PRTFIL). This is useful to make your functions as efficient as possible.
For other functions you will generally have the option to influence the amount of default code and functionality that will be generated by the 2E code generators by detailing the level of referential integrity you wish the function to have.
Careful consideration should be given to setting the format relations to the desired level. These are MANDATORY, OPTIONAL, USER, NO ERROR and of course, DROPPED. I fully recommend the best practice of RTFM.
Function Options
Most function options are self explanatory and most of us the industry standard which don't deviate too far away from the model defaults. Some function options in particular are important to understand how they are used.
Close down program when set to ‘Y’ will close the program. If this program is likely to me called repeatedly in an iteration or a data loop (i.e. RTVOBJ) then consideration should be given to setting this to ‘N’
Reclaim resources is generally set for functions that are on menu’s.
Share Subroutine. See chapter on setting this value.
Function Wrapping
Function wrapping is the process of converting snippets of action diagram logic into a standalone function. This can be either an EXCEXTFUN or an EXTINTFUN. By copying the action diagram code into the developers notepad you have the option to convert the code into the standalone function.
At this point 2e will create parameter interfaces for each of the function contexts that are used in the code snippet and reference these as duplicate parameters using the PR1 to PR9 special contexts.
Whilst this works perfectly well you will notice that the function parameter interface is quite unwieldy. If this is the case sometimes you might find it easier to build the function yourself. You choose?, flip a coin.
To minimise this, the developer must manually make alterations.
Review the fields in the WRK and LCL contexts and determine if they are local to the code snippet only or need to be passed into the new function. If local;-
Replace all action diagram logic referring to the PRx contect of the fields with WRK or LCL.
Remove unused fields from the parameter interface.
If it turns out thar all fields are not needed then remove the parameter line entry for the context.
Note the restrictions of the EXCEXTFUN and EXCINTFUN function types when wrapping code. This chapter will be coming soon.....
Share and share alike – Subroutines that is
Any internal database function can be generated as a shared or reusable subroutine. The system option (YSHRSBR) will be set to NO, therefore the individual function option must be used to identify a shared subroutine. Additionally an EXCINTFUN can be implemented as a subroutine rather than inline code and thus subsequently also shared.
The decision to make an internal function shared is subjective. In many cases there will be no particular advantage because the generated code is relatively small or because the number of times the function is called is small. Sharing a function will also in itself add extra lines of code for parameter passing.
You should only consider using shared subroutines where there is an obvious benefit in reducing the number of lines of generated code.
The answer to a large function with many lines of code may be to redesign the call structure rather than to just use the easy option of using shared subroutines. Note that a function called many times may not be the best one to make as shared. It may be a higher level function in the call structure, which will provide the most benefit.
A shared subroutine cannot cope with specific indicators. Therefore, a shared subroutine function should not send error messages to a screen. It will be unable to identify the correct screen field error indicator so that the field cannot be highlighted and the cursor cannot be positioned.
It is good programming style that any function, which has output parameters, should always perform a logic path that initialises or sets output fields. E.g. A RTVOBJ to GET attributes should initialise or set all output parameters whether a record is found or not. A shared subroutine will always cause the output fields to be set with some value but this is not the case if the subroutine is not shared. Thus if a subroutine is shared and contains output parameters that are not set they may contain unpredictable data.
An EXCINTFUN may be made into a subroutine but not necessarily shared. This enables a *QUIT to be added. The *Quit will jump to the end of the subroutine.
As a matter of best practice a model file's default CHGOBJ, CRTOBJ or DLTOBJ should remain unshared.
Next time the great PGM.*Return code debate.........
Thanks for reading.
Lee.
No comments:
Post a Comment
Thanks for considering leaving some comments about my random rants for everything software development and more.