[Sc-devel] environment-safe functions

James Harkins jamshark70 at gmail.com
Sat Nov 24 11:56:52 PST 2007


Since the lists are back (yay!)...

While updating ad hoc class syntax to remove the inconvenient "self"  
arguments, I had to come up with another mechanism to handle  
asynchronous functions (by which I mean any function that executes  
later than its appearance in the code, including callbacks for buffer  
reading, various responder functions [MIDI, OSC, HID, GUI],  
notification functions as in Updater or NotificationCenter, any  
scheduled function, etc.).

If you're in one environment when you declare such a function and  
expect the function to act within the same environment, currently the  
only way to do this is to save the current environment manually and  
account for it explicitly in the action function. That's a pain.

a = AdhocClass({
	~prep = { |path|
		~buf = Buffer.read(s, path, action: { |buf|
			~numCh = buf.numChannels;
			~numFr = buf.numFrames;
			~dur = ~numFr / buf.sampleRate;
		});
	};
});

(b = a.copy).prep("sounds/a11wlk01.wav");
b.listVars;
--> Variables:
--> [ buf, Buffer(0, 188893, 1, 44100, sounds/a11wlk01.wav) ]
// Buffer info is not in the right environment!

b.buf.free;

Then I realized a simple function wrapper would do the job:

+ Function {
	envirSafe {
		var	envir = currentEnvironment;
		^{ |... args| envir.use({ this.valueArray(args) }) }
	}
	
	e { ^this.envirSafe }   // short form: e { ... } makes envir-safe func
}

I'm okay with keeping this extension in my library, but I think it's  
a more general problem than that. I have a feeling most users would  
think, well, I created the function in such and such an environment,  
so why does it switch environments on me? It's a point of confusion  
that is probably unnecessary. Also, it doesn't strike me as a  
deliberate design decision -- it seems more like nobody thought about  
how these functions would interact with environments, and the current  
behavior is there just because it's easier (for developers, not users).

If I had my druthers, we'd go through and make everything environment  
safe, but that might be too risky or have unwanted performance  
implications for people who are using lots of environments... in  
which case, I might suggest adding these methods into the main  
library and I would be happy to document it in the relevant places.

Thoughts?

The above example works like this:

a = AdhocClass({
	~prep = { |path|
		~buf = Buffer.read(s, path, action: envirSafe { |buf|
			~numCh = buf.numChannels;
			~numFr = buf.numFrames;
			~dur = ~numFr / buf.sampleRate;
		});
	};
});

hjh


: H. James Harkins
: jamshark70 at dewdrop-world.net
: http://www.dewdrop-world.net
.::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..:

"Come said the Muse,
Sing me a song no poet has yet chanted,
Sing me the universal."  -- Whitman

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.create.ucsb.edu/pipermail/sc-devel/attachments/20071124/ecb2aeb9/attachment.htm


More information about the Sc-devel mailing list