How to reference the object using a symbol?

If I have

var asynth=Synth(\sine);
var str=\asynth;

How do I convert str to reference asynth? I guess I could use currentEnvironment[str] , but is there another way?

If you want to reference things by name, put them in an Event (or IdentityDictionary).

~mySynths = ();
~mySynths.asynth = Synth(\sine); // store the Synth
~mySynths.asynth; // access the Synth

Yes, but I’d like to know if it is possible to construct a name asynth as a string or symbol and use that to reference an already instantiated object named asynth. If asynth is a global, currentEnvironment has a dictionary that can be referenced by name. Are there any other ways?

No.

There is no situation in SuperCollider where you can do this with declared vars.

hjh

This only works for ‘global’ variables.

~foo = 1;
currentEnvironment[\foo] === ~foo

There are however several classes (factories) that store their instances in a named collection. Basically, any class with def in the name will do this.

You could make your own class to do this if you wanted to…
Here is a quick one. The interface is not the most helpful, but it will work. You’d probably want to copy all the constructors from Synth to make it more usable, adding a ‘name’ arg.

SynthStore {
	classvar store;
	*new {|name, msg ...args|
		store = store ?? {()};
		store[name.asSymbol] = Synth.perform(msg.asSymbol, *args);
		^store[name.asSymbol]
	}
	*get {|name|
		^store[name];
	}
}

Now to use it…

SynthDef(\test, { Out.ar(0, SinOsc.ar()) }).add;

SynthStore(\testInstance, \new, \test);
// synth instance was made

SynthStore.get(\testInstance).free
// synth instance was freed

Or…
you could use a global store, like Library to store anything.

Library.put(\abs, Synth(\test))Library.at(\abs).free

Basically, these are all other ways of doing what @Spacechild1 suggested.

Doing exactly what you ask, is probably possible with some weird string based reflection. Turning the function into a string and parsing it before compilation. But here’s the problem. When you declare a var it has a scope attached to it. That is, how long the object will exist for - usually, this is the curly braces surrounding it. You cannot access that variable outside of its scope, as it will be deleted at the closing curly (conceptually). If you tried to, hopefully the interpreter would crash or throw an error, or else there would be some undefined behaviour. That is why doing what you asked, whilst probably possible (albeit, difficult), is a bad idea.

The two methods above are different ways of storing the object in different scopes, so that it outlives the current scope. From there, you can address them based on their associated key.

Thanks ! The code examples have really cleared up some of the supercollider concepts that aren’t immediately apparent in the help browser tutorials.