Explicitly include a boost "windows" folder even on linux
[supercollider.git] / HelpSource / Classes / Environment.schelp
bloba345ca8a18b2325d2fcc572e5efb6e4277492f33
1 CLASS::Environment
2 related::Classes/Event, Classes/IdentityDictionary
3 categories::Collections>Unordered
4 summary:: A dictionary which can serve as a 'name space' for functions
6 DESCRIPTION::
7 An Environment is an IdentityDictionary with additional features that allow it to serve as a 'name space' within which functions can be defined and/or evaluated.
9 CLASSMETHODS::
10 method::stack
11 Maintains a stack of Environments accessed by link::#*push:: and link::#*pop::.
13 method::make
14 Creates a new Environment and sends make message.
16 method::use
17 Creates a new Environment and sends use message.
19 method::push
20 Saves link::#.currentEnvironment:: on the stack.
22 method::pop
23 Restores link::#.currentEnvironment:: from the stack.
25 INSTANCEMETHODS::
27 method::make
28 Evaluates the function within the environment, returns the environment.
30 method::use
31 Evaluates the function within the environment, returns the return value of the function.
33 method::push
34 Saves the receiver on the stack.
36 method::pop
37 Restores link::#.currentEnvironment:: from the stack.
42 SECTION::PseudoVariables (global variables)
43 These are not methods, but global variables.
44 method:: currentEnvironment
45 determines environment used by "~" syntax, link::#.valueEnvir::, and link::#.valueArrayEnvir::
47 method:: topEnvironment
48 initial value of link::#.currentEnvironment::, can be used for 'global variables'
50 SECTION::Related Messages
52 method:: valueEnvir (arg1, arg2...)
53 evaluates a function, looking up unspecified arguments in link::#.currentEnvironment::
55 method:: valueArrayEnvir (argArray)
56 same as link::#.valueEnvir::, but with arguments in an array
59 SECTION::Overview
61 subsection::topEnvironment, currentEnvironment, make and use
63 When SuperCollider starts, it creates an Environment that it stores in the pseudovariables link::#.topEnvironment:: and link::#.currentEnvironment::. The link::#.topEnvironment:: provides a universally accessible collection of named values similar to the link::Classes/Interpreter:: variables a, b, c, ....
65 The compiler provides a shortcut syntax where ~ is a placeholder for link::#.currentEnvironment::.
66 This makes the expression code::~myvariable;:: equivalent to code::currentEnvironment.at(\myvariable);:: and the expression code::~myvariable = 888;:: equivalent to code::currentEnvironment.put(\myvariable, 888);::
68 The messages link::#*make::(function) and link::#*use::(function) replace link::#.currentEnvironment:: with the receiver. The message link::#*make:: is intended to be used when initializing an Environment, so it returns the Environment. The message link::#*use:: is for evaluating a functions within an Environment, so it returns the return value of the function.
70 For example
71 code::
73 a = Environment.make({
74         ~a = 100;
75         ~b = 200;
76         ~c = 300;
77 });
78 a.postln;
81 creates an environment, while
82 code::
83 a.use({
84         ~a + ~b + ~c
85 }).postln;
87 evaluates the function within that environment.
89 subsection::valueEnvir and valueArrayEnvir
91 When Functions are evaluated with link::#.valueEnvir:: and link::#.valueArrayEnvir:: unspecified arguments are looked up in the current Environment.
92 If the argument is not found in the Environment its default value is used.
93 code::
95 var f;
97 // define a function
98 f = { arg x, y, z; [x, y, z].postln; };
100 Environment.use({
101         ~x = 7;
102         ~y = 8;
103         ~z = 9;
105         f.valueEnvir(1, 2, 3);  // all values supplied
106         f.valueEnvir(1, 2);     // z is looked up in the current Environment
107         f.valueEnvir(1);        // y and z are looked up in the current Environment
108         f.valueEnvir;           // all arguments are looked up in the current Environment
109         f.valueEnvir(z: 1);     // x and y are looked up in the current Environment
113 Now here is how this can be used with an instrument function. Environments allow you to define instruments without having to worry about argument ordering conflicts. Even though the three functions below have the freq, amp and pan args declared in different orders it does not matter, because link::#.valueEnvir:: looks them up in the environment.
114 code::
115 s.boot;
118 var orc;
119 orc = Environment.make {
120         ~a = { arg freq, amp, pan;
121                 Pan2.ar(SinOsc.ar(freq), pan, amp);
122         };
123         ~b = { arg amp, pan, freq;
124                 Pan2.ar(RLPF.ar(Saw.ar(freq), freq * 6, 0.1), pan, amp);
125         };
126         ~c = { arg pan, freq, amp;
127                 Pan2.ar(Resonz.ar(GrayNoise.ar, freq * 2, 0.1), pan, amp * 2);
128         };
129         ~orc = [~a, ~b, ~c];
131 // 'reverb'
132 { var in; in = In.ar(0, 2); CombN.ar(in, 0.2, 0.2, 3, 1, in); }.play(addAction: \addToTail);
134 { loop({
135         orc.use({
136                         // set values in the environment
137                 ~freq = exprand(80, 600);
138                 ~amp = 0.1;
139                 ~pan = 1.0.rand2;
141                         // call a randomly chosen instrument function
142                         // with values from the environment
144                  x = { ~orc.choose.valueEnvir; }.play(fadeTime: 0.2, addAction: \addToHead);
145                  0.2.wait;
146                  x.release(0.2);
147         });
148 }) }.fork;
153 subsection::Environments and asynchronous functions
155 Local variables declared in functions, and class and instance variables, use lexical scope. That is, the context in which they are understood depends on where the declaration is read during compilation. Asynchronous functions -- any function that will execute outside (later than) the current execution flow -- carry their lexically scoped variables with them.
156 code::
157 f = { var a = "got it"; { a.postln }.defer(0.5) };
158 f.value;
160 Asynchronous functions include any scheduled function, responder function associated with OSCFunc, MIDIFunc, HID or GUI action functions, or actions used in server messaging (such as Buffer.read, Buffer or Bus .get, and so on).
162 Environment variables have dynamic scope; they are read from whichever environment is current, whether or not it was the current environment when the function was declared. For instance, the following fails because e is no longer the current environment when the deferred function wakes up.
163 code::
164 e = (a: "got it", f: { { ~a.postln }.defer(0.5) });
165 e.use { e.f };
167 link::Classes/Function#inEnvir#Function's inEnvir:: method attaches a function to a specific environment. If no environment is given, the current environment at the time of executing inEnvir is the default.
168 code::
169 e = (a: "got it", f: { { ~a.postln }.inEnvir.defer(0.5) });
170 e.use { e.f };
173 subsection::Using Environments as object prototypes
175 Environment's strong::know:: variable holds a link::Classes/Boolean:: value controlling whether the Environment may be used as an object prototype or not. If strong::know:: is true, any messages sent to the Environment that it does not already understand will be relayed into items in the Environment. (If false, not-understood messages will produce a standard "does not understand" error message.)
177 The default for know is false for Environment, and true for link::Classes/Event::.
178 code::
179 e = Environment[
180         'someVariable' -> 5,
181         'printMe' -> { |self, string| string.postln }
184 e.know = true;
186 More typically, Events are used to define such prototypes because the syntax is simpler.
187 code::
188 e = (someVariable: 5, printMe: { |self, string| string.postln });
192 An object prototype looks up the method selector in the Environment to decide what to do.
194 Most objects are simply returned -- the method call behaves like a getter for any other object.
195 code::
196 e.someVariable;
197 // same as
198 e.at('someVariable');
199 e['someVariable'];
201 If the selector is a setter, e.g. strong::someVariable_(value):: or strong::someVariable = value::, the new value is put into the Environment.
202 code::
203 e.someVariable = 10;
204 // same as
205 e.put('someVariable', 10);
207 If the Environment item is a function, it is evaluated as if it were a method definition. The first argument passed into the function is the Environment that holds the function; arguments to the method call follow as the second, third etc. arguments passed into the function.
208 code::
209 e.printMe("Oh hai wrldz");
210 // same as
211 e['printMe'].value(e, "Oh hai wrldz");
213 The function may access objects in the Environment using the first function argument.
214 code::
215 e.mul2 = { |z| z.someVariable * 2 };
216 e.mul2;
218 Environment variables inside a function will refer to the currently active environment -- not to the Environment being addressed. This is to allow the object prototype to interact with the link::#.currentEnvironment::.
219 code::
220 e.mul2 = { |z| ~someVariable * 2 };
221 // this will throw an error because ~someVariable is nil in the currentEnvironment
222 e.mul2;
224 If you wish to access objects in the environment using environment variable syntax, 'use' the environment within the function.
225 code::
226 e.mul2 = { |z| z.use { ~someVariable * 2 } };
227 e.mul2;
230 note::
231 Be careful to avoid method names that are defined in any of the superclasses of environment (or event). Object prototyping works by trapping method selectors that are not already defined as class library methods. Using a generic method selector such as 'stop' or 'reset' will cause the corresponding class library method to respond, and the items in the environment will never be checked.
233 Assigning a value into an environment using a setter -- strong::name_():: or strong::.name = ...:: -- posts a warning message if the name is already defined in the class library.
234 code::
235 e.reset = { "My reset function".postln };
237 // prints:
238 WARNING:
239 'reset' exists a method name, so you can't use it as pseudo-method.
241 // this does NOT execute the reset function above
242 // because Object:reset responds
243 e.reset;