Updating a LookupTable
value appears to silently create a new LookupTable
instance, instead of modifying the existing one. The documentation for LookupTable
suggests that the class is based on Vector
and this appears to contradict the documentation for Vector
: the difference between Vector
and List
is that a Vector
is modified in place and modifying a List
leaves the original list intact and creates a new list.
Anyway, here’s an example to illustrate:
#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>
startRoom: Room 'Void'
"This is a featureless void. "
;
me: Person
location = startRoom
// Random nonsense in the form of a lookup table
config = [
'foozle' -> [
'value' -> 'default string',
'options' -> [ 'foo', 'bar' ]
]
]
configFlag = nil
// Given a list and an optional prompt, get input from the player
// until they type something that matches one of the items from the
// list.
getWordFromList(lst, prompt?) {
local i, n, txt;
n = nil;
// Set a default prompt if one wasn't given as an arg
if(!prompt)
prompt = '\b>';
while(n == nil) {
// Display the prompt
"<<prompt>>";
// Get a line of input
txt = inputManager.getInputLine(nil, nil);
// Get the input, less any leading or trailing spaces
if(rexMatch('<space>*(<alpha>+)<space>*$', txt) != nil)
n = rexGroup(1)[3];
if(n) {
for(i = 1; i <= lst.length; i++) {
// If the typed input is the starting
// bit of one of the items in the list,
// return the matching full item
if(lst[i].startsWith(n))
return(lst[i]);
}
// Nothing matched, prompt and try again
n = nil;
}
}
return(n);
}
// Handle a single config question.
// The arg is the key for the stanza in the lookup table
configQuestion(id) {
local cfg, pr;
// Get the requested stanza or give up
cfg = config[id];
if(!cfg) return;
// Construct the question prompt from the options
pr = cfg['options'].join('/');
// Get the player input
cfg['value'] = getWordFromList(cfg['options'], pr + ' >');
// IMPORTANT: This needs to be uncommented
//config[id] = cfg;
}
desc() {
local cfg;
// First time through we prompt the player for input
if(!configFlag) {
"Pick one:\n ";
configQuestion('foozle');
configFlag = true;
}
// We always output the configured value
cfg = config['foozle'];
"Foozle is <q><<cfg['value']>></q>. ";
}
;
versionInfo: GameID
name = 'sample'
byline = 'nobody'
authorEmail = 'nobody <foo@bar.com>'
desc = '[This space intentionally left blank]'
version = '1.0'
IFID = '12345'
;
gameMain: GameMainDef
initialPlayerChar = me
;
This game-like thing contains nothing but the starting room and the player. When the player does >X ME
(or the equivalent) the first time, they’re prompted to make a choice: type FOO
or BAR
. This theoretically updates me.config['foozle']['value']
to be whatever the player entered, which is then displayed.
The code as presented above doesn’t work, however:
>x me
Pick one:
foo/bar >foo
Foozle is "default string".
Instead of updating the value, it stays the default. On the other hand if you edit the line marked IMPORTANT in the comments, so configQuestion()
is now:
configQuestion(id) {
local cfg, pr;
// Get the requested stanza or give up
cfg = config[id];
if(!cfg) return;
// Construct the question prompt from the options
pr = cfg['options'].join('/');
// Get the player input
cfg['value'] = getWordFromList(cfg['options'], pr + ' >');
// IMPORTANT: This needs to be uncommented
config[id] = cfg;
}
It now works:
>x me
Pick one:
foo/bar >foo
Foozle is "foo".
The only difference is that in the first example we set cfg
to be config[id]
and then cfg['value']
to be the player input, and stop there. In the working example, we then also set config[id]
to be cfg
before returning. Which will only matter if cfg
was copied by value instead of reference, or something like that.
This is all using frobtads, which reports its version as:
FrobTADS 2.0
TADS 2 virtual machive v2.5.17
TADS 3 virtual machine v3.1.3 (mjr-T3)
FrobTADS copyright (C) 2009 Nikos Chantziaras.
TADS copyright (C) 2009 Michael J. Roberts.
FrobTADS comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of FrobTADS under certain terms and conditions.
See the file named COPYING for more information.
So is this a bug, a misunderstanding on my part, or something more exciting and esoteric?