3 // abstract class that dispatches assignment / reference in environments.
11 ^super.newCopyArgs(envir ?? { Environment.new(32, Environment.new) })
14 ^this.new.make(function)
17 ^this.new.use(function)
19 *newFrom { arg aCollection;
20 var newCollection = this.new;
21 aCollection.keysValuesDo({ arg k,v, i; newCollection.put(k,v) });
25 // override in subclasses
33 dispatch.value(key, obj);
36 localPut { arg key, obj;
44 // behave like environment
60 if(currentEnvironment !== this) {
61 Environment.push(this)
62 } { "this environment is already current".warn }
67 // pushes the Envir, executes function, returns the Envir
68 // usually used to create an environment by adding new variables to it.
69 var result, saveEnvir;
71 saveEnvir = currentEnvironment;
72 currentEnvironment = this;
76 currentEnvironment = saveEnvir;
81 // temporarily replaces the currentEnvironment with this,
82 // executes function, returns the result of the function
83 var result, saveEnvir;
85 saveEnvir = currentEnvironment;
86 currentEnvironment = this;
88 result = function.value(this);
90 currentEnvironment = saveEnvir;
99 keysValuesDo { arg function;
100 envir.keysValuesDo(function);
103 keysValuesArrayDo { arg argArray, function;
104 envir.keysValuesArrayDo(argArray, function);
106 findKeyForValue { arg val;
107 ^envir.findKeyForValue(val)
109 sortedKeysValuesDo { arg function;
110 envir.sortedKeysValuesDo(function);
112 putAll { arg ... dictionaries;
113 dictionaries.do {|dict|
114 dict.keysValuesDo { arg key, value;
124 clear { envir.clear }
126 know_ { arg flag; envir.know = flag }
129 doesNotUnderstand { arg selector ... args;
132 if (selector.isSetter) {
133 selector = selector.asGetter;
134 ^this[selector] = args[0];
136 ^this.doFunctionPerform(selector, args)
139 ^this.superPerformList(\doesNotUnderstand, selector, args);
142 doFunctionPerform { arg selector, args;
144 if(envir[selector].isNil) {
145 ^envir[\forward].functionPerformList(\value, this, selector, args);
148 ^this[selector].functionPerformList(\value, this, args);
151 linkDoc { arg doc, pushNow=true;
152 doc = doc ? Document.current;
154 if(pushNow and: { currentEnvironment !== this }) { this.push };
157 unlinkDoc { arg doc, popNow = false;
158 doc = doc ? Document.current;
159 if(doc.envir === this) { doc.envir_(nil) };
160 if(popNow and: { currentEnvironment === this }) { this.pop };
164 dispatch_ { arg disp;
165 dispatch = disp.envir_(this);
167 envir_ { arg argEnvir;
169 if(dispatch.notNil) { this.dispatch = dispatch };
177 LazyEnvir : EnvironmentRedirect {
178 var <>proxyClass=\Maybe;
181 ^proxyClass.asClass.new
186 proxy = super.at(key);
188 proxy = this.makeProxy(key);
189 envir.put(key, proxy);
196 this.at(key).source_(obj);
197 dispatch.value(key, obj); // forward to dispatch for networking
202 proxy = envir.removeAt(key);
203 if(proxy.notNil) { proxy.clear };
206 localPut { arg key, obj;
207 this.at(key).source_(obj);