[adv3Lite] What's special about "propType(&prop) == TypeNil"

Dear Eric and other adv3Lite users,

I’m trying to define a new TAction in my game, and I noticed something I don’t quite understand.

My verb, being a TAction, takes a single object. Let’s call the verb “Rub”. Only one object responds to the verb in a complex way, others just display some text. But since I want different objects to respond with different text, it seems a burden to write dobjFor(Rub) for everything, and I want to define a “rubDesc” property similar to the “listenDesc” already implemented in adv3Lite.

And of course, there is still a default text for a large number of objects, so I have the dobjFor(Rub) method of Thing class to test if rubDesc property is defined, and if not, display the default text.

Sample code:

[code]DefineTAction( Rub );
VerbRule( Rub ) ‘rub’ singleDobj : VerbProduction
action = Rub
verbPhrase = ‘rub/rubbing (what)’
missingQ = ‘what do you want to rub’
;

modify Thing
rubDesc = nil
dobjFor( Rub ) {
action() {
if ( rubDesc == nil ) { // This doesn’t work as expected
"It doesn’t achieve anything. ";
} else {
rubDesc;
}
}
}
;[/code]
However, this doesn’t quite work. I looked up in adv3Lite’s source code, and found out that the library uses “propType(&prop) == TypeNil” test. I changed the line in my code to “if ( propType( &rubDesc ) == TypeNil ) {”, and it worked. (The library also uses “display(rubDesc);” but that’s not related.)

My question is, what is special about the propType(&prop) == TypeNil test? The “dobjFor()” is a macro, and the above code should expand to the “actionDobjRub()” method of Thing. Why can’t it use the rubDesc == nil test then? Does this have something to do with how propertyset works?

Thanks in advance,
Ming

I think the problem here is that when rubDesc isn’t nil it’s a double-quoted string, which is in effect an instruction to display something rather than a value, so if you try to compare a double-quoted string to nil it won’t work as expected. Using propType(&rubDesc) does the job safely (this is a feature of the TADS 3 language; it’s not specific to adv3Lite).

An alternative coding pattern you could consider is:

modify Thing
    rubDesc = "It doesn't achieve anything. ";
    dobjFor( Rub ) {
        action() {
                 rubDesc;           
        }
    }
;

I think I understand now. Since double-quoted string is a little like a function, whenever I do the “rubDesc == nil” comparison, the string is actually printed, and something like a return value of the printing is compared to nil instead of the content of the string. That explains the weird result I’m getting. I also understand better why the library (both adv3 and adv3Lite) uses both single-quoted strings (most of the XXXMsg) and double-quoted strings (most of the XXXDesc) now.

And because I’m not likely to implement rubDesc other than double-quoted string or a method, your alternative pattern works better, too. I’ll definitely consider it.

Thanks Eric!