Beeping Button Brouhaha
Expected an integer, got nil evt.ex.fr.type;type.ref.frame -48406 (#6008D229).buttonClickScript(), 27: PushConstant NIL Entering break loop: level 1We're still in our
buttonClickScript
, about to execute the code at program counter 27. Here's the NewtonScript code for the buttonClickScript
:
func() begin local beeps := StringToNumber(numBeeps.text); for i := 1 to beeps do :SysBeep(); endLet's look at the disassembled code for the
buttonClickScript
:
Disasm(GetCurrentFunction(0)) 0: FindVar numBeeps 1: Push 'text 2: GetPath 1 3: Push 'StringToNumber 4: Call 1 5: SetVar beeps 6: PushConstant 1 7: SetVar i 8: GetVar beeps 9: SetVar i|limit 10: PushConstant 1 11: SetVar i|incr 12: GetVar i|incr 13: GetVar i 14: Branch 23 17: PushSelf 18: Push 'SysBeep 19: Send 0 20: Pop 21: GetVar i|incr 22: IncrVar i 23: GetVar i|limit 24: BranchIfLoopNotDone 17 27: PushConstant NIL 28: Return #2 NILWe're about to execute the code at offset 27--it looks as though we're at the end of the loop. Let's look at the values of our variables to see if they are reasonable:
GetAllNamedVars(0); #4419641 {beeps: NIL, i: 1, i|limit: NIL, i|incr: 1, numBeeps: {_parent: {#4418345}, _proto: {#6008D5D9}, viewCObject: 0x110A57D, entryLine: {#44186F5}, labelLine: {#44181FD}, width: 73, indent: 75, height: 13}, text: "Beep", SysBeep: <function, 0 arg(s) #350E8D>}It doesn't seem right that
beeps
is nil
. In fact, that would explain the error we got. The for
loop expected an integer, but got nil
. But why is beeps
nil
? It was obtained from calling StringToNumber
on numBeeps.text
. Let's start by looking at numBeeps
more closely:
numBeeps := GetNamedVar(0, 'numBeeps); #4417EA9 {_parent: {_parent: {#4411D11}, _proto: {#6008D0C1}, viewCObject: 0x110A483, numBeeps: <2>, viewclipper: 17863765, base: <1>, viewFlags: 577}, _proto: {viewBounds: {#6008D689}, label: "Num Beeps:", entryFlags: 10753, _proto: {@189}, debug: "numBeeps", preAllocatedContext: numBeeps}, viewCObject: 0x110A57D, entryLine: {_parent: <2>, _proto: {#356429}, viewCObject: 0x110A58C, viewFlags: 10753, viewBounds: {#4418301}, text: "2"}, labelLine: {_parent: <2>, _proto: {#356569}, viewCObject: 0x110A5C2, text: "?Num Beeps:", viewFont: {@100}, viewBounds: {#44181E1}}, width: 73, indent: 75, height: 13}Now let's look at the value of the
text
slot in numBeeps
. Expecting to find the value of 2, we get a surprise instead:
numBeeps.text #4632AD ""There isn't a
text
slot in the numBeeps
view or template. So the value of numBeeps.text
must be coming from the protoLabelInputLine itself. Notice, however, that there does seem to be a text
slot with the value "2"
in numBeeps.entryLine
. But of course! For a protoLabelInputLine, the input text isn't found in the text
slot of the labelInputLine view, but in the text
slot of the child view where the input is actually done (see "protoLabelInputLine" on page 177). With this bit of fresh information we can now modify the code in the buttonClickScript
. Our code should actually be
func() begin local beeps := StringToNumber(numBeeps.entryLine.text); for i := 1 to beeps do :SysBeep(); end
An online version of Programming for the Newton using Macintosh, 2nd ed. ©1996, 1994, Julie McKeehan and Neil Rhodes.
Last modified: 1 DEC 1996