I have a question...wait, nevermind

I’ve asked a lot of TADS3-related questions here over the past several months, but there are even more questions that I almost asked, but worked out the answer for myself in the process of asking the question.

This is probably because I’m in the habit of trying to reproduce the problem in a little self-contained minimalistic-but-compilable example. And often in writing out a version of the problem code without anything else, either it turns out that the problem wasn’t in the bit I thought it was, or just framing the sample code to illustrate what simple things the problem isn’t, what the problem is suddenly becomes apparent.

Anyway, I know that I personally search the forums for old posts whenever I have a problem, so I was wondering if it makes sense to post topics that are “just” solutions, rather than are questions that need to be answered.

Like for example, I recently was briefly flummoxed by the semantics of invoking a callback via a property on an object. Specifically, if obj._callback is a function assigned to a property on the object, then (_callback)() and (self._callback)() produce different results (when used in methods on obj). So:

#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>

class CallbackThing: object
        _callback = nil
        construct(fn) { _callback = fn; }
        foo() { return((_callback())); }
        bar() { local v = _callback; return(v()); }
        baz() { return((self._callback)()); }
;
DefineIAction(Foozle)
        _callbackThing = nil

        _getCallbackThing() {
                if(_callbackThing == nil)
                        _callbackThing = new CallbackThing(function() {
                                return('[foozle]');
                         });
                return(_callbackThing);
        }
        execAction() {
                local obj;

                obj = _getCallbackThing();
                "Foo is <q><<toString(obj.foo())>></q><.p> ";
                "Bar is <q><<toString(obj.bar())>></q><.p> ";
                "Baz is <q><<toString(obj.baz())>></q><.p> ";
        }
;
VerbRule(Foozle) 'foozle' : FoozleAction verbPhrase = 'foozle/foozling';
startRoom:      Room 'Void'
        "This is a featureless void. "
;
me:     Person
        location = startRoom
;
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
;

…produces:

Foo is "function#91267 "

Bar is "[foozle]"

Baz is "[foozle]"

In this case an anonymous function is assigned to (an instance’s) CallbackThing._callback. This produces different results if it is called (via methods on CallbackThing) as (_callback()) versus (self.callback)() (or fn = _callback; fn()). Which is not what I would have expected.

Not a big deal or anything, but I spent more time on working out the problem then I would’ve had to if searching for “TADS callback” produced any meaningful results.

That’s one specific example, but I think I’ve almost asked many questions, only to hit “cancel” instead of “Create Topic” at the last moment because I’d just discovered the solution. And it recently struck me that if I encountered the same problem again in a couple months, there’s a fair chance that I’d have forgotten the solution (because it’s somewhat counterintuitive, and I’m not constantly writing code that involves the problematic syntax), and since I never asked the question there’d be no record of either the problem or the solution.

2 Likes

Speaking personally, I’d find it hugely useful to have it all recorded somewhere. Either here and/or collated in one place, like in Jim Nelson’s TADS Cookbook. Saves having to ask the same question over again!

2 Likes

I was writing the same. Hence agree with Christopher, even if you find the solution in typing the question, please post anyway, simply changing the post’s wording from “how to do this… ?” into “here is how to do this…”, a thing I strongly suspect is “super-easy” for people accustomed to edit code and text basically in parallel :smiley:

Best regards from Italy,
dott. Piergiorgio.

(whose indeed hold a if/src/[language]/forum directory for those nifty snippets…)

1 Like

Random helpful hint:

In Learning TADS 3 the documentation for TravelConnector contains an error. It gives the usage for getDestination() as being getDestination(traveler, origin), when it’s actually getDestination(origin, traveler).

Spent way too long running in circles over that one because I assumed the problem was in the mess of conditionals in my code, not the documentation.

2 Likes