1 // abstract class that dispatches assignment / reference in environments.
9 ^super.newCopyArgs(envir ?? { Environment.new(32, Environment.new) })
12 ^this.new.make(function)
15 ^this.new.use(function)
17 *newFrom { arg aCollection;
18 var newCollection = this.new;
19 aCollection.keysValuesDo({ arg k,v, i; newCollection.put(k,v) });
23 // override in subclasses
31 dispatch.value(key, obj);
34 localPut { arg key, obj;
42 // behave like environment
58 if(currentEnvironment !== this) {
59 Environment.push(this)
60 } { "this environment is already current".warn }
65 // pushes the Envir, executes function, returns the Envir
66 // usually used to create an environment by adding new variables to it.
67 var result, saveEnvir;
69 saveEnvir = currentEnvironment;
70 currentEnvironment = this;
74 currentEnvironment = saveEnvir;
79 // temporarily replaces the currentEnvironment with this,
80 // executes function, returns the result of the function
81 var result, saveEnvir;
83 saveEnvir = currentEnvironment;
84 currentEnvironment = this;
86 result = function.value(this);
88 currentEnvironment = saveEnvir;
97 keysValuesDo { arg function;
98 envir.keysValuesDo(function);
101 keysValuesArrayDo { arg argArray, function;
102 envir.keysValuesArrayDo(argArray, function);
104 findKeyForValue { arg val;
105 ^envir.findKeyForValue(val)
107 sortedKeysValuesDo { arg function;
108 envir.sortedKeysValuesDo(function);
110 putAll { arg ... dictionaries;
111 dictionaries.do {|dict|
112 dict.keysValuesDo { arg key, value;
122 clear { envir.clear }
124 know_ { arg flag; envir.know = flag }
127 doesNotUnderstand { arg selector ... args;
130 if (selector.isSetter) {
131 selector = selector.asGetter;
132 ^this[selector] = args[0];
134 ^this.doFunctionPerform(selector, args)
137 ^this.superPerformList(\doesNotUnderstand, selector, args);
140 doFunctionPerform { arg selector, args;
142 if(envir[selector].isNil) {
143 ^envir[\forward].functionPerformList(\value, this, selector, args);
146 ^this[selector].functionPerformList(\value, this, args);
149 linkDoc { arg doc, pushNow=true;
150 doc = doc ? Document.current;
152 if(pushNow and: { currentEnvironment !== this }) { this.push };
155 unlinkDoc { arg doc, popNow = false;
156 doc = doc ? Document.current;
157 if(doc.envir === this) { doc.envir_(nil) };
158 if(popNow and: { currentEnvironment === this }) { this.pop };
162 dispatch_ { arg disp;
163 dispatch = disp.envir_(this);
165 envir_ { arg argEnvir;
167 if(dispatch.notNil) { this.dispatch = dispatch };
175 LazyEnvir : EnvironmentRedirect {
176 var <>proxyClass=\Maybe;
179 ^proxyClass.asClass.new
184 proxy = super.at(key);
186 proxy = this.makeProxy(key);
187 envir.put(key, proxy);
194 this.at(key).source_(obj);
195 dispatch.value(key, obj); // forward to dispatch for networking
200 proxy = envir.removeAt(key);
201 if(proxy.notNil) { proxy.clear };
204 localPut { arg key, obj;
205 this.at(key).source_(obj);