[View]  [Edit]  [Lock]  [References]  [Attachments]  [History]  [Home]  [Changes]  [Search]  [Help] 

sunit[s8] Block closures

We have reported issues with blocks, so... comments and tests follows.

1 - Return from wrong context (in recursion)

! Object methodsFor: #examples !
example1

    ^self example1Helper: nil! !

! Object methodsFor: #examples !
example1Helper: aBlock

    aBlock isNil ifTrue: [
        self example1Helper: [^true].
        ^false
   ].
   aBlock value.
   ^false! !

TestCase 
   subclass: #TestClosures
   instanceVariableNames: ''
   category: 'sunit-s8'!

! TestClosures methodsFor: 'test'!
test1
   | result |
   result:= false.
   [(1 example1 == true) ifTrue:[ 
      result:= true]
   ] on: Error do: [ self print: 'TEST FAILED - wrong block semantics' ].
   self assert: result! !


2 - (failure) Nested returns

This test expose the bug when the exit op throw exception outside of scope.
"2 - Nested returns"
! Object methods !
example2
  self print: #example2 ,$ ,self.
  true ifTrue: [
    self print: #level1.
    ^true ifTrue: [
        self print: #level2.
        ^12 odd
    ]
  ].
  self print: #example2 ,$ ,#shouldNotRunHere!  !

! TestClosures methodsFor: 'test'!
test2
   | result |
   result:= false. 
   [(1 example2 = false) ifTrue:[ 
      result:= true]
   ] on: Error do: [ self print: 'TEST FAILED - wrong block semantics' ].
   self assert: result! !   

Explanation of the bugs

example1The selector is used to catch stReturn exception, ... do not work on recursion (or activations with same message selector)
example2The generated code defer evaluation of handler function, to section outside exception coverage.

Proposal