call a routine after "after()" with a specific verb

Which approach is best?

I am wondering which way to make a routine run either before or after action(), as to let certain parameters be set in the background, is the best?

I would rather not use ‘inherited’ in the action-routine. I have solved it now with an extra routine called from dobjFor() {action() {}} like this:

class Whatever : Thing
	x = 0
	dobjFor(TheVerb)	
	{ 
		action()
		{
			self.TheVerbMsg;
			x += 2;
		}
	}
	TheVerbMsg()
	{
		//Say something default here...
	}
;

X : Whatever
dobjFor(TheVerb)
{
	TheVerbMsg()
	{
		"I'm certain now that the x will be increased with 2... But I'm not happy with this extra routine. ";
	}
};

This is OK, but I would much rather wish a functionality of the type below. Is this possible somehow? And If so, how do I go about implementing it?

class Whatever : Thing
	x = 0
	dobjFor(TheVerb)
	{
		action()
		{
			//Say something default here...
		}
		runThisAfterAction() 	//(For the specific verb)
		{
			x += 2;
		}
	};

X : Whatever
dobjFor(TheVerb)
{
	action()
	{
		"I'm certain now that the x will be increased with 2...";
	}
};

Or is this option the only one left?

class Whatever : Thing
	x = 0
	dobjFor(TheVerb)
	{
		action()
		{
			x += 2;
			defaultReport("default message to be overridden...");
		}
	};

X : Whatever
dobjFor(TheVerb)
{
	action()
	{
		"I'm certain now that the x will be increased with 2... but then I need to remember to add inherited here somewhere";
		inherited;
	}
};

Well there are beforeAction and afterAction methods defined on Thing class which are called on objects involved or related to an action. But you should study details in the documentation as the set of selected object which are notified about an action is quite broader than just the dobj/iobj: “Receive notification that a command is about to be performed. This is called on each object connected by containment with the actor performing the command, and on any objects explicitly registered with the actor, the actor’s location and its locations up to the outermost container, or the directly involved objects.” And inside you can test for example gActionIs(Take) and similar.

So there are alternative possibilities where to intercept the processing of an action, but that doesn’t mean that it is the best practice. Actually i think that your last example is how it is meant to be done and in me eyes quite optimal solution. Maybe I don’t understand why you don’t like it or don’t like to call inherited, but IMHO most of the library is implemented that way.

I like to stick to the general convention of things, especially in programming languages, so maybe I’ll stick to the last example. I’m just a little concerned that I will forget to add “inherited;” :confused:

Ok, now I understand. The explicit need to call inherited manually is design decision of TADS 3 language. It’s a general concept you must not forget not only in this situation but almost in any work with TADS and its library. Although it could be a source of not so easily spotted bugs when you accidentally forget, I believe that Mike did it this way because it brings quite some degree of flexibility - you can choose whatever you want call inherited processing on the beginning, in the middle or after you customization or suppress the default handling at all or even choose which superclass behavior to inherit.

Ok. That makes sense. Thanks for your answer.