Refer to dictionary in class via class name

Hi there

I’d like to be able to do something like this:

Synths[\tb303]

… or …

Synths(\tb303)

… where Synths is a class (not an instance) and by providing the value \tb303 I’m accessing an item in a dictionary which is presumably a classvar of Synths.

In SC we can do something similar with Pdef because we can refer to (for example) Pdef(\myPattern), where presumably all the declared Pdefs are stored in a dictionary somewhere.

I’ve looked at the code for Pdef but I’m stuffed if I can work it out. Can anyone help?

Save somewhere in your Extensions directory Synths.sc:

Synths {
  classvar synths;

  *initClass {
    synths = ();
  }

  *new { |symbol, value|
    if (value.notNil) { synths[symbol] = value };
    ^synths[symbol];
  }
}

Recompile (cmd-shift-L or ctrl-shift-L). Then you can assign like this:

Synths(\hello, 6)

And retrieve like this (nil for unassigned fields):

Synths(\hello) // -> 6
Synths(\something) // -> nil

Is this the right idea?

Thank you Eric. So I think I understand. You’re using the constructor to return a value from the internal dictionary (an Event in your case).

The side effect of this is that, because I’m using the constructor, I’m creating an instance of Synths every time I want to access an item in the class-level dictionary. I assume that if I don’t assign the instance to a variable then it would be garbage collected? (I’m thinking about avoiding having lots of pointless class instances accumulating in memory.)

There are no constructors in sc, the ‘*new’ method is the long form of Class(), and ‘value’ for ‘a()’ respectively. So you aren’t making any instances here.

and

To fill in just a little detail – there are no syntactic constructors in SC, yes.

New objects are instantiated by going into one of two primitives, _Object_New or _Object_NewCopyArgs (whose precise names I haven’t verified in the class library). I think(?) these are the only ways an object can be instantiated. (It is definitely impossible in SC to instantiate an object without invoking a primitive to allocate it.) Typically you get there in a *new method by returning ^super.new with some type of initialization.

If you’re not super.new-ing up the class tree to reach Object *new, then you’re not instantiating anything.

The proposed Synths *new doesn’t do super.new, hence it isn’t creating object instances, so no worries.

That is, it’s up to the class to decide how to respond to new – it isn’t enforced that new always means “construct a new object.”

hjh

Thanks for the detailed explanation; that makes sense.