argument of ifNotNil: must be a 0-argument block

Mathieu mathk.sue at gmail.com
Sat Sep 2 00:51:01 UTC 2006


Zulq Alam a écrit :
> Thanks. I was curious how much this might save so I did a little test
> that is most probably flawed :o).
> 
> | association |
> association := #A -> #Z.
> MessageTally spyOn:
>     [10000000 timesRepeat:
>         [| key |
>         key := association key.
>         key ifNotNil: [key yourself].
>         key yourself]].
> MessageTally spyOn:
>     [10000000 timesRepeat:
>         [association key ifNotNilDo: [:key | key yourself].
>         key yourself]].
> 
> On my system #ifNotNilDo costs about 0.000557 ms whereas the inlined
> version is virtually free (~0.0001 ms).
> 
> Also, while doing this I found what looks to be a bug with regard to the
> scope of the block temporary.
> 
> | x |
> x := 10.
> x ifNotNilDo: [:y | ].
> y factorial    "y isn't in scope!"
> 
> This can be done in a workspace though I couldn't put it in a method.


This is because block are inline in the method so scope of temps is the method. It's not really good
to have this but I think it was a question of memory space(ask Marcus Denker).

You have also notice that the return statement always know were to return from when it is in block.
That how interpreter know, by creating a context that point the bytecode were the block start in the
method.

For more clear information you can read :
http://www.iam.unibe.ch/~ducasse/FreeBooks/CollectiveNBlueBook/oe-tour-sept19.pdf
and:
http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_imp_toc.html

Math

> 
> Thanks,
> Zulq.
> 
> 
> Ken Causey wrote:
>> As Andreas points out this is because this apparent method call is
>> actually compiled by the compiler.  (And the error is actually from the
>> compiler, not a result of sending the message.)  Perhaps incorrectly
>> depending on your point of view.  I would recommend using 'ifNotNilDo:'
>> instead when you want the offending object.
>>
>> Ken
>>
>> On Sat, 2006-09-02 at 00:25 +0100, Zulq Alam wrote:
>>> Hi List,
>>>
>>> Why does "Object new ifNotNil: [:object | ]" result in the syntax
>>> error "argument of ifNotNil: must be a 0-argument block" when the
>>> code appears to be fine with this?
>>>
>>>
>>> ProtoObject>>ifNotNil: ifNotNilBlock
>>>     "Evaluate the block, unless I'm == nil (q.v.)"
>>>
>>>     ^ ifNotNilBlock valueWithPossibleArgs: {self}
>>>
>>>
>>> BlockClosure>>valueWithPossibleArgs: anArray
>>>
>>>     | n |
>>>     (n := self numArgs) = 0 ifTrue: [^ self value].
>>>     n = anArray size ifTrue: [^ self valueWithArguments: anArray].
>>>     ^ self valueWithArguments: (n > anArray size
>>>         ifTrue: [anArray, (Array new: n - anArray size)]
>>>         ifFalse: [anArray copyFrom: 1 to: n]): anArray
>>>
>>>
>>>
>>> A quick search of Mantis for ifNotNil or valueWithPossibleArgs hasn't
>>> left me any wiser. Something to do with the interpreter, perhaps
>>> optimisation?
>>>
>>> Thanks,
>>> Zulq.
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>>
> 
> 
> 




More information about the Squeak-dev mailing list