Method prototyping

When ever i find myself writing the same thing over and over again i know there’s usually a better way to do it. So, is there a good way to write “prototypes” for methods when writing classes, when you want all methods to include the same things? E.g.

methodA {|input|
	fork{ // all methods should have this fork
		if(aCertainThing.notNil, {
			anotherClass.initCondition.wait; // a Condition that signals when ready
		});

		//...specific things to this method here...
		
		this.play;
		anotherClass.initCondition = nil;
	};
}

Should i use a wrapper method like below, or is there a better way?

prMethod {|method, ...args|
	fork{
		if(aCertainThing.notNil, {
			anotherClass.initCondition.wait; // a Condition that signals when ready
		});
		
		this.perform(method, ...args);
		
		this.play;
		anotherClass.initCondition = nil;
	};
}

Yes you can use the wrapper method in each of your methods, or you can catch all the messages in one method, apply your wrapping code then call the matching private unwrapped method:

MyClass {

    doesNotUnderstand { | selector...args |
        (this.class ++ " does not understand method " ++ selector);

        if(UGen.findRespondingMethodFor(selector).notNil) {
            "But UGen understands this method".postln
        };
    }
}

a = MyClass();
a.someMethodThatDoesNotExist

see end of http://doc.sccode.org/Guides/WritingClasses.html

1 Like

Caveat: Every class understands every method defined in Object. Those method selectors cannot be overridden this way.

hjh

1 Like

Thanks! I’ll try that. Maybe this is will complicate other things though, yes…

Design-wise, I think the best you can hope for is:

+TheClass {
    method1 {
        |a, b|
        this.waitAndDo {
            (a + b).postln;
        }
    }

    method2 {
        this.waitAndDo {
            this.stop;
        }
    }
    
    prWaitAndDo {
        |function|
        fork {
            
            if (aCertainThins.notNil) {
                anotherClass.initCondition.wait; // a Condition that signals when ready
            };
            
            protect {
                function.value();
            } {
                this.play;
                anotherClass.initCondition = nil;
            }
        }
    }
}

It’s a little bit of boiler-plate for every method (two lines…), but it’s clear and easy to read and you don’t have to mess with any weird method naming or doesNotUnderstand trickery.