#REFACTORING by stefan
class: Lazy
added: #_evaluate_
comment/format in:
#block:
#examples
changed: #doesNotUnderstand:
protocol compatibility with LazyValue
nil Semaphores when evaluated.
--- a/Lazy.st Wed Jun 29 18:27:52 2016 +0200
+++ b/Lazy.st Thu Jun 30 16:59:13 2016 +0200
@@ -76,49 +76,51 @@
"
Evaluates the factorial, starting only when the
result is actually required (when printString is sent).
- [exBegin]
+ [exBegin]
| fac |
fac := [100 factorial] lazyValue.
Transcript showCR: 'Doing nothing. '.
(Delay forSeconds: 2) wait.
Transcript showCR: fac printString.
- [exEnd]
+ [exEnd]
- Starts evaluating both factorials only when required (by the touch),
+ Starts evaluating both factorials only when required (by the value),
and waits until both blocks have finished before continuing.
- [exBegin]
+ [exBegin]
| fac1 fac2 |
fac1 := [Transcript showCR: 'Starting fac1.. '. 100 factorial] lazyValue.
fac2 := [Transcript showCR: 'Starting fac2.. '. 120 factorial] lazyValue.
- fac2 touch.
- fac1 touch.
+ fac2 value.
+ fac1 value.
Transcript showCR: 'both completed.'.
- [exEnd]
+ [exEnd]
Demonstrates how to pass arguments to a lazy evaluation block.
- [exBegin]
+ [exBegin]
| temp |
temp := [:x :y :z | x * y * z] lazyValueWithArguments: #(2 3 4).
Transcript showCR: temp printString.
- [exEnd]
+ [exEnd]
"
! !
!Lazy methodsFor:'evaluating'!
block: aBlock
- "Execute aBlock in parallel, but ensure that any messages sent
- to me before execution of the block has terminated are
- suspended until it has terminated. Do not start the evaluation
- until at least one message has been sent to the receiver."
+ "Execute aBlock in parallel, but ensure that any messages sent
+ to me before execution of the block has terminated are
+ suspended until it has terminated. Do not start the evaluation
+ until at least one message has been sent to the receiver."
- startSemaphore := Semaphore new.
- endSemaphore := Semaphore new.
- [startSemaphore wait.
- result := aBlock value.
- endSemaphore signal] fork
+ startSemaphore := Semaphore new.
+ endSemaphore := Semaphore new.
+ [
+ startSemaphore wait.
+ result := aBlock value.
+ endSemaphore signal
+ ] fork.
!
block: aBlock value: aValue
@@ -175,13 +177,28 @@
!Lazy methodsFor:'synchronising'!
+_evaluate_
+ "answer the computed value"
+
+ |startSema endSema|
+
+ startSema := startSemaphore.
+ startSema notNil ifTrue:[
+ startSema signal. "Start the evaluation."
+ endSema := endSemaphore.
+ endSema notNil ifTrue:[
+ endSema waitUncounted. "Wait until evaluation completed."
+ ].
+ startSemaphore := endSemaphore := nil.
+ ].
+
+ ^ result
+!
+
doesNotUnderstand: aMessage
"Any message to a Lazy will end up here."
- startSemaphore signal. "Start the evaluation."
- endSemaphore waitUncounted. "Wait until evaluation completed."
-
- ^ aMessage sendTo:result
+ ^ aMessage sendTo:self _evaluate_
! !
!Lazy methodsFor:'testing'!