Inform 7 Home Page / Documentation


§20.7. Making new text with text substitutions

Substitutions are most often used just for printing, like so:

say "The clock reads [time of day].";

But they can also produce text which can be stored up or used in other ways. For example, defining

To decide what text is (T - text) doubled:
    decide on "[T][T]".

makes

let the Gerard Kenny reference be "NewYork" doubled;

set this temporary variable to "NewYorkNewYork".

There is, however, a subtlety here. A text with a substitution in it, like:

"The clock reads [time of day]."

is always waiting to be substituted, that is, to become something like:

"The clock reads 11:12 AM."

If all we do with text is to print it, there's nothing to worry about. But if we're storing it up, especially for multiple turns, there are ambiguities. For example, suppose we're changing the look of the black status line bar at the top of the text window:

now the left hand status line is "[time of day]";

Just copying "[time of day]" to the "left hand status line" variable doesn't make it substitute - which is just as well, or the top of the screen would perpetually show "9:00 AM".

On the other hand, looking back at the phrase example:

To decide what text is (T - text) doubled:
    decide on "[T][T]".

"[T][T]" is substituted immediately it's formed. That's also a good thing, because "T" loses its meaning the moment the phrase finishes, which would make "[T][T]" meaningless anywhere else.

What's going on here is this: Inform substitutes text immediately if it contains references to a temporary value such as "T", and otherwise only if it needs to access the contents. This is why "[time of day]" isn't substituted until we need to print it out (or, say, access the third character): "time of day" is a value which always exists, not a temporary one.

Another case where that might be important is if we want to set a text to an elaborated version of itself. For example, suppose there is a variable (not a temporary one) called "the accumulated tally", and consider this:

now the accumulated tally is "[the accumulated tally]X";

The intention of the writer here was to add an "X" each time this happens. But the result is a hang, because what it actually means is that accumulated tally can only be printed if the accumulated tally is printed first... an infinite regress. The safe way to do this would be:

now the accumulated tally is the substituted form of "[the accumulated tally]X";

Using the adjectives "substituted" and "unsubstituted", it's always possible to test whether a given text is in either state, should this ever be useful. For example,

now the left hand status line is "[time of day]";
if the left hand status line is unsubstituted, say "Yes!";

will say "Yes!": the LHSL is like a bomb waiting to go off. Speaking of which:

The player is holding a temporal bomb.

When play begins:
    now the left hand status line is "Clock reads: [time of day]".

After dropping the temporal bomb:
    now the left hand status line is the substituted form of the left hand status line;
    say "Time itself is now broken. Well done."

This is making use of:

substituted form of (text) ... text

This takes a text and makes substitution occur immediately. For example,

substituted form of "time of death, [time of day]"

produces something like "time of death, 9:15 AM" rather than "time of death, [time of day]". It's entirely legal to apply this to text which never had any substitutions in, so

substituted form of "balloon"

produces "balloon".

Note that there's no analogous phrase for "unsubstituted form of...", because once text has substituted, there's no way to go back.


arrow-up.png Start of Chapter 20: Advanced Text
arrow-left.png Back to §20.6. Regular expression matching
arrow-right.png Onward to §20.8. Replacements

*ExampleIdentity Theft
Allowing the player to enter a name to be used for the player character during the game.

*ExampleMirror, Mirror
The sorcerer's mirror can, when held up high, form an impression of its surroundings which it then preserves.

**ExampleThe Cow Exonerated
Creating a class of matches that burn for a time and then go out, with elegant reporting when several matches go out at once.