Use include files to duplicate code
- Last Updated: April 9, 2024
- 4 minute read
- OpenEdge
- Version 13.0
- Documentation
Now it is time for another digression to introduce you to a powerful feature
of ABL that is helpful in completing the temp-table example. You might have noticed that
to pass a temp-table from one procedure to another, you need to have an equivalent
temp-table definition in both procedures. So the next thing you have to do in the
Customers and Orders window is define the same
temp-table as you just did in h-fetchOlines.p so
you can use it as an INPUT parameter to the RUN statement to that procedure. Surely there must be a
better way to duplicate code than retyping it or coping and pasting it?
ABL provides a mechanism for just this purpose, called an include file. An include file is a source procedure that is included in another procedure file to form a complete procedure that you can then compile. Using include files saves you from having to copy and paste code from one procedure to another when you need the same definition or other code in multiple places. More important, it can also save you from many maintenance headaches when you need to change the duplicated code. Rather than having to identify all the places where the code exists and change every one of them consistently, you just have to change the one include file and recompile the procedures that use it.
Having said this, it is important to make an observation about include files
in an OpenEdge application. In later chapters, you learn how to use dynamic language
constructs to allow the same procedure to work many different ways. For example, you can
use them to manage a query on different tables or with different WHERE clauses that are defined dynamically at run time or to build a
window that can display fields and a browse for many different tables, with all the
objects defined dynamically, so their attributes can be changed at run time. This limits
the need for include files in many cases.
In earlier applications written before these dynamic features existed, ABL
developers used include files to pass in, for example, the name of a table or a list of
fields or a WHERE clause for a FOR EACH statement. In this way, the same procedure could be compiled many
different ways to do similar jobs. With dynamic programming, you can often modify the
same kinds of procedure attributes at run time, allowing a single compiled procedure to
handle all the cases that you need, without creating many different .r files for all the different cases, or compiling and
running procedures on the fly during program execution. For that reason, once you have
learned about dynamic programming, if you find yourself doing extraordinarily complex or
clever things with include files in a new application, you should consider whether you
could do the same job more easily and more effectively with dynamic language constructs
that are part of the language for exactly this purpose.
With these disclaimers aside, it is still valuable to know about include files and when you might use them. If nothing else, you will find many include file references in existing ABL code.
The syntax for an include file is extremely simple. You merely place the
include filename, enclosed in braces ( { } ) into your procedure
exactly where you want the code it contains to be inserted. This can be anywhere at all
in your procedure. An include file can contain a complete statement, a whole set of
statements, a partial statement, a single keyword or name, or even a fraction of a name,
depending on what purpose it serves. The only limitation is that ABL always inserts a
single space after (but not before) the contents of the include file when it pulls it in
during the compilation. This means you could append a partial name or keyword directly
to the end of a code fragment in the main procedure, but not to the beginning without a
space being inserted.
By convention, include files end in the .i extension, but this is not actually required. If ABL
needs a pathname relative to the Propath to locate your include file, then you need to
include the pathname within the braces just as you would specify a relative pathname as
part of the filename in a RUN statement. (Note that the
ABL does not search libraries for include files.)
In the simplest case, an include file just inserts the contents of the file
into the procedure that includes it when the main procedure is compiled. You can also
define arguments to include files. To add an argument to an include file, place the
string {1} into the include file where you want the argument inserted.
Then, in each include file reference, add the value of the argument after the name of
the include file, separated by a space. For example, in the next section you replace the
four button triggers for the First, Next, Prev, and
Last buttons with an include file. The code
for all of those buttons is the same except for the one keyword in the GET statement FIRST,
NEXT, PREV, and
LAST. You can write all four triggers with one
include file by adding an argument to the include file. If you call it h-ButtonTrig1.i, then the first line of code in h-ButtonTrig1.i is GET {1}
CustQuery. And the trigger for the First button becomes {h-ButtonTrig.i
FIRST}.
For multiple arguments to an include file, just mark them with placeholders
{1}, {2}, and so on. You can also
create named arguments that let you determine the arguments you pass into
the include file when it becomes part of the compilation. For a complete
description of include files and their arguments, see the { } Include file reference
topic in the ABL Reference.