# HG changeset patch # User Stefan Vogel # Date 1467298753 -7200 # Node ID e913680689bfeb5766f535ea1c029dfa1e0b12a8 # Parent cbe2e415bb782547114f69d14b172a0792b85bb8 #REFACTORING by stefan class: Lazy added: #_evaluate_ comment/format in: #block: #examples changed: #doesNotUnderstand: protocol compatibility with LazyValue nil Semaphores when evaluated. diff -r cbe2e415bb78 -r e913680689bf Lazy.st --- 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'!