'From Squeak5.3alpha of 22 March 2019 [latest update: #18478] on 18 April 2019 at 2:36:33 pm'!
ProcessSpecificVariable subclass: #DynamicVariable
	instanceVariableNames: 'value outer'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Kernel-Processes-Variables'!
!DynamicVariable commentStamp: 'mvl 3/13/2007 13:55' prior: 0!
My subclasses are dynamic variables: each subclass represents a variable
whose value persists inside the block passed to #value:during:. There is
no way to change the value inside such a block, but it is possible to
temporarirly rebind it in a nested manner.!


!DynamicVariable methodsFor: 'accessing' stamp: 'mt 4/18/2019 14:31'!
allValues

	^ Array streamContents: [:stream |
		self allValuesDo: [:anObject |
			stream nextPut: anObject]]!
]style[(9 3 1 7 15 3 6 1 1 3 4 1 12 1 1 1 8 1 1 4 6 1 8 1 8 1 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;! !

!DynamicVariable methodsFor: 'accessing' stamp: 'mt 4/18/2019 10:59'!
outer
	^ outer!
]style[(5 2 1 6)b,cblack;,c126000000,cblack;! !

!DynamicVariable methodsFor: 'accessing' stamp: 'mt 4/18/2019 10:59'!
outer: aDynamicVariable
	outer := aDynamicVariable.!
]style[(6 1 16 8 2 1 16 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;! !

!DynamicVariable methodsFor: 'accessing' stamp: 'mt 4/18/2019 10:58'!
value
	^ value!
]style[(5 2 1 6)b,cblack;,c126000000,cblack;! !

!DynamicVariable methodsFor: 'accessing' stamp: 'mt 4/18/2019 10:58'!
value: anObject
	value := anObject.!
]style[(6 1 8 8 2 1 8 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;! !

!DynamicVariable methodsFor: 'accessing' stamp: 'mt 4/18/2019 14:31'!
withAllValues

	^ Array streamContents: [:stream |
		self withAllValuesDo: [:anObject |
			stream nextPut: anObject]]!
]style[(13 3 1 7 15 3 6 1 1 3 4 1 16 1 1 1 8 1 1 4 6 1 8 1 8 1 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;! !


!DynamicVariable methodsFor: 'enumerating' stamp: 'mt 4/18/2019 14:30'!
allValuesDo: block

	self outerScopesDo: [:outerScope |
		block value: outerScope value].!
]style[(12 1 5 3 4 1 14 3 10 1 1 3 5 1 6 1 10 1 5 2)b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!DynamicVariable methodsFor: 'enumerating' stamp: 'mt 4/18/2019 14:27'!
outerScopesDo: block

	self outer ifNotNil: [:outerScope |
		block value: outerScope.
		outerScope outerScopesDo: block].!
]style[(14 1 5 3 4 1 5 1 9 3 10 1 1 3 5 1 6 1 10 4 10 1 14 1 5 2)b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cred;,cblack;,c000000126,cblack;! !

!DynamicVariable methodsFor: 'enumerating' stamp: 'mt 4/18/2019 14:30'!
withAllValuesDo: block

	block value: self value.
	self allValuesDo: block.!
]style[(16 1 5 3 5 1 6 1 4 1 5 3 4 1 12 1 5 1)b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!DynamicVariable methodsFor: 'enumerating' stamp: 'mt 4/18/2019 14:27'!
withOuterScopesDo: block

	block value: self.
	self outerScopesDo: block.!
]style[(18 1 5 3 5 1 6 1 4 3 4 1 14 1 5 1)b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !


!DynamicVariable methodsFor: 'accessing - convenience' stamp: 'mt 4/18/2019 14:27'!
outerScopes

	^ Array streamContents: [:stream |
		self outerScopesDo: [:outerScope |
			stream nextPut: outerScope]]!
]style[(11 3 1 7 15 3 6 1 1 3 4 1 14 1 1 1 10 1 1 4 6 1 8 1 10 1 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;! !

!DynamicVariable methodsFor: 'accessing - convenience' stamp: 'mt 4/18/2019 14:25'!
withOuterScopes

	^ Array streamContents: [:stream |
		self withOuterScopesDo: [:outerScope |
			stream nextPut: outerScope]]!
]style[(15 3 1 7 15 3 6 1 1 3 4 1 18 1 1 1 10 1 1 4 6 1 8 1 10 1 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

DynamicVariable class
	instanceVariableNames: ''!

!DynamicVariable class methodsFor: 'accessing' stamp: 'mt 4/18/2019 14:32'!
scope
	^ Processor activeProcess environmentAt: self ifAbsent: []!
]style[(5 2 1 11 13 1 14 1 4 1 9 3)bu,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!DynamicVariable class methodsFor: 'accessing' stamp: 'mt 4/18/2019 14:33'!
value

	^ self scope
		ifNil: [self default]
		ifNotNil: [:currentScope | currentScope value]!
]style[(5 3 1 1 4 1 5 3 6 2 4 1 7 4 9 3 12 1 1 1 12 1 5 1)bu,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;! !

!DynamicVariable class methodsFor: 'accessing' stamp: 'mt 4/18/2019 14:16'!
value: anObject during: aBlock

	| p outerScope outerScopeWasDynamic |
	p := Processor activeProcess.
	outerScopeWasDynamic := true.
	outerScope := p
		environmentAt: self
		ifAbsent: [outerScopeWasDynamic := false. nil].

	^[
		p environmentAt: self put: (self new value: anObject; outer: outerScope).
		aBlock value ] 
			ensure: [ outerScopeWasDynamic 
				ifTrue: [p environmentAt: self put: outerScope]
				ifFalse: [p environmentRemoveKey: self ifAbsent: []] ].!
]style[(6 1 8 1 7 1 6 3 1 1 1 1 10 1 20 1 1 2 1 1 2 11 13 3 20 1 2 1 4 3 10 1 2 1 1 3 14 1 4 3 9 2 20 1 2 1 5 2 3 5 1 4 1 1 14 1 4 1 4 1 1 4 1 3 1 6 1 8 2 6 1 10 1 4 6 1 5 7 7 3 20 6 7 1 1 1 1 14 1 4 1 4 1 10 1 5 8 1 1 1 1 21 1 4 1 9 1 2 1 3)bu,cblack;,c000000126,cblack;,bu,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126,c000126000,cblack;! !
