Antwort: BlockContext and returns...

Boris_Gaertner at msg.de Boris_Gaertner at msg.de
Tue Jan 22 10:06:58 UTC 2002


Benoit St-Jean wrote:
  >>For instance why would you write:

  >>anObject isFoo
  >>   ifTrue: [^#foo]
  >>   ifFalse: [^#bar]

  >>instead of:

  >>^anObject isFoo
  >>   ifTrue: [#foo]
  >>   ifFalse: [#bar]

  >>I always thought that clean blocks was the way to go and
  >>that you should always try to avoid returning from
  >>inside a block when possible, so what's the deal here?

Yes, I think a block without a return is the better solution,
BUT:  ifTrue:ifFalse: is inlined, and I think the blocks are
removed due to inlining. So the difference does not matter here.

Nevertheless, the use of return is a question of style and I prefer
    ^anObject isFoo
       ifTrue: []
       ifFalse: []
This form clearly states the fact that we will return,
while
     anObject isFoo
       ifTrue: [ <...> ^#foo]
       ifFalse: [<...> ^#bar]
hides this fact. 



To the best of my understanding, there is only one
situation that requires a return within a block:

  foo
    self doSomethingOnFailure: [^false].
    self doSomthingElse.
    ^true

  doSomethingOnFailue: failureBlock
     <...>
     failureBlock value
     <...>

This is essentially a nonlocal jump: The evaluation of
"failureBlock value" causes the method foo to be left
with result value  false. That is, from doSomethinOnFailue:
we jump back to the place where  foo  was called. 


  >>BTW, if you look at senders of ifTrue:ifFalse: (or
  >>vice-versa) you only get a few methods...  Is it
  >>broken or that is the normal "behavior" since that
  >>"message" is inlined and not reaaly a message send?


Yes, inlined methods can not found by "senders of... ".
"senders of ... " scans compiled methods for attached
message symbols, and for an inlined message no
message symbol is attached.

It is sometimes asked whether methods that are inlined
by the compiler are needed in the image at all. They
are needed because they can be sent with a perform.

Try this (in some class): 

test

   | string idx |

    string := 'hello>>Benoit'.
    idx := 1.
    [(string at: idx) = $>]
       perform: #whileFalse:  with: [idx := idx + 1]. 
    ^string copyFrom: idx to: string size. 

This method will be found as a sender of  #whileFalse:.

When you insert a  "self halt."  in  BlockContext>>whileFalse:
and execute the method, the debugger will stop at the halt. 

The following example is a bit tricky: 

   | string idx |

    string := 'hello>>Benoit'.
    idx := 1.
    [(string at: idx) = $>]
       whileFalse: [idx := idx + 1];  " NOT inlined "
       whileTrue: [idx := idx + 1].   " inlined "
    string copyFrom: idx to: string size.

Squeak 3.2 does not accept this as valid code (why ??), some
other Smalltalks do. Those who do (Visual Works and IBM Smalltalk),
create a message send instruction for the first block (that is,
the method BlockContext>>whileFalse: will be executed)  and
inlined code for the second block (the method Blockcontext>>whileTrue:
will not be executed). The well-known Digitalk Smalltalk V/286 crashed 
with a general protection fault, but that was a compiler bug that could
be fixed after decompilation of the compiler.

Bye

Boris 

msg  systems ag
Fraunhoferstraße 9
85737 Ismaning

Tel.: (+89) 96 101 546
mailto: Boris_Gaertner at msg.de
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20020122/a31f711d/attachment.htm


More information about the Squeak-dev mailing list