Code includes method source + a few attempts to make use of it.

I’m trying to reach an understanding of “practical usage”

I’m already familiar with TempoClock.cmdPeriod, as well as the source for CmdPeriod… so perhaps we can move from there & make this quick:

l = LinkClock ( )

l.sched(0, r { 88.rand.postln; 1.0.yieldAndReset })



+ Function {
	doOnCmdPeriod { this.value }

+ Object {
	doOnCmdPeriod { ^this.cmdPeriod } // compatibility


// compatibility ?

// ^^ ERROR: Message 'cmdPeriod' not understood.

{ "test".postln } . doOnCmdPeriod
// ^^ "test"
// ^^ a Function

// ^^ no additional behavior 

LinkClock.doOnCmdPeriod { "exec immediately" }
// ^^ LinkClock

// ?


Seeking practical usage for .doOnCmdPeriod

LinkClock inherits from TempoClock.

TempoClock implements a class method *cmdPeriod.

Your test is trying to call an instance method, which is undefined for this class.

TempoClock adds itself as a class to CmdPeriod (see *initClass). So, when the user does cmd-., CmdPeriod calls TempoClock.doOnCmdPeriod. This isn’t defined specifically, so it falls back to Object:doOnCmdPeriod – this is a bit confusing, but classes are themselves instances of Class, so they do have access to instance methods defined in Object. Within Object:doOnCmdPeriod, this is the class TempoClock – so you end up at TempoClock.cmdPeriod.

Anyway, you asked about practical usage:

  • Don’t call either cmdPeriod or doOnCmdPeriod by yourself. These are not user facing methods.

  • If you’re writing a class, and specific instances of that class need to do something upon cmd-dot (but perhaps not all instances), then you should implement doOnCmdPeriod as an instance method within that class. Then, users should do CmdPeriod.add(myInstance).

  • If you’re writing a class, and all instances need to do something upon cmd-dot, then follow the TempoClock model: 1. The class keeps a list of all its instances. 2. The class implements *doOnCmdPeriod. 3. The class’s *initClass also does CmdPeriod.add(this) (where this is the class).


1 Like