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 classTempoClock – 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).