|Using the "system_file" and "replace" Directives In the Same Source File|
here is an obscurity that presents itself when using both the replace and system_file directives in the same file.
First, to bring this article into context, let me describe briefly what they each do:
The system_file directive tells the compiler that the following routines, contained in the current source file, can be overridden via the replace directive. (It actually does more, but this is the behavior that is relevant)
The replace directive, generally called before the inclusion of the system_file, is used to indicate that certain routines are to be replaced. Specifically, when the replace directive is used to specify a routine name, instances of that routine, which occur under the scope of the system_file directive, are ignored. This way a new version, specified in a non-system file can be used instead.
The problem-behavior is that a file, which 1) specifies a function to be replaced, 2) implements a new version of the function, and 3) is designated as a system_file, has just specified its own implementation of the replaced function to be ignored as well. Compiling this file will result in an error message similar to:
For personal library extensions in particular, the need to replace standard library routines and provide new routines that can be replaced as well is common. What we seem to need, in cases like this is to specify some routines as replaceable and other routines as not replaceable.
The solution is rooted in the fact that the name of the system_file directive is potentially misleading since it seems to imply an entire file will be treated as a system file. Actually, this is not true. The manner in which the Inform compiler handles files designated as "system files" begins only when the directive is encountered and stops at the end of the file. This enables us to move the system_file directive down in our source file. The routines specified after the system_file directive will be able to be replaced by games implementing the file, while the routines above the system_file directive will be compiled without the system_file qualifier and can therefore be used as replacements to library routines.
The following code snip demonstrates: