Unexpected behavior
Do the following and see what happens:
- Create a subclass of nil called Test.
- Implement doesNotUnderstand: as ^self.
- Evaluate Test new ifTrue: [4] ifFalse: [5].
... then let's see how he does, up there, without all the assistance!
Do the following and see what happens:
Posted by
Andrés
at
15:30
6 comments:
Heh, something funny was bound to happen. Seasoned Smalltalkers know that the system cheats at the level of some special selectors, #ifTrue:ifFalse: is one of those.
If you put the code into a method of Test the behaviour will stay the same, then if you use the inspector to drill down into the methodDictionary of the class you can see the byte code of your method which will explain it all ;-)
Let's not forget that mustBeBoolean is answered by the object via DNU before jump false executes.
Andres.
#mustBeBoolean is only sent by the simulator (e.g. when stepping with the debugger).
In my compiled method I see no send of it, and in my virgin 7.6 image the only sender of #mustBeBoolean is Context>>jump:if:.
(I could post the byte codes here, but I don't want to spoil this exercise for others ;-)
I spoke too soon: I went over the VM sources and just learnt that the JIT generates an isBoolean check for the conditional branch byte codes, so it is natural that #mustBeBoolean is not visible in the byte code.
Technically, I do not feel the VM is cheating... jumpFalse could be implemented (in Smalltalk) as
false == thisContext topOfStack
and in that case, we would still have the same behavior without hitting DNU in Test.
Andres.
Not quite... the DNU is interacting weirdly with the upcalled mustBeBoolean... try this code:
Smalltalk.Core defineClass: #Test
superclass: nil
indexedType: #none
private: false
instanceVariableNames: ' '
classInstanceVariableNames: ''
imports: ''
category: 'Kernel-Classes'.
Core.Test compile: 'doesNotUnderstand: message ^false '.
answerOne := Core.Test new ifTrue: [4 ] ifFalse: [5] .
Core.Test compile: 'mustBeBoolean ^false '.
answerTwo := Core.Test new ifTrue: [4 ] ifFalse: [5] .
answerOne -> answerTwo
Post a Comment