... then let's see how he does, up there, without all the assistance!
Do the following and see what happens:
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) asfalse == thisContext topOfStackand 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:  .Core.Test compile: 'mustBeBoolean ^false '.answerTwo := Core.Test new ifTrue: [4 ] ifFalse:  .answerOne -> answerTwo
Post a Comment