Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Tutorials / Mark_Polishook_tutorial / 22_Runtime_errors.schelp
blobc5d50084fee9b9aa42a8c3d54eaba45ac48568ba
1 title:: 22_Runtime_errors
2 summary:: Mark Polishook tutorial
3 categories:: Tutorials>Mark_Polishook_tutorial
4 related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial
6 section::Runtime errors
8 Runtime errors occur while a program is executing.
10 section::Common errors
12 numberedList::
13 ## an object receives a message which it doesn't understand
14 ## a binary operation (addition, subtraction, multiplication, etc.) can't be performed
15 ## a value other than true or false appears in a conditional (boolean) test
16 ## a file can't be opened (a primitive fails)
19 section::Object doesn't understand
21 In the case of
23 code::
24 3.createRuntimeError
27 SuperCollider prints a four-part error notification to the post window. The parts of the notification are ERROR, RECEIVER, ARGS, and CALL STACK, as in
29 code::
30 ERROR: Message 'createRuntimeError' not understood.
31 RECEIVER:
32    Integer 3
33 ARGS:
34 Instance of Array {    (057E7560, gc=01, fmt=01, flg=11, set=00)
35   indexed slots [0]
37 CALL STACK:
38         DoesNotUnderstandError-reportError
39                 arg this = <instance of DoesNotUnderstandError>
40         Nil-handleError
41                 arg this = nil
42                 arg error = <instance of DoesNotUnderstandError>
43         Object-throw
44                 arg this = <instance of DoesNotUnderstandError>
45         Object-doesNotUnderstand
46                 arg this = 3
47                 arg selector = 'createRuntimeError'
48                 arg args = [*0]
49         < closed FunctionDef >  (no arguments or variables)
50         Interpreter-interpretPrintCmdLine
51                 arg this = <instance of Interpreter>
52                 var res = nil
53                 var func = <instance of Function>
54         Process-interpretPrintCmdLine
55                 arg this = <instance of Main>
58 ////////////////////////////////////////////////////////////////////////////////////////////////////
60 The ERROR section explains what went wrong. The RECEIVER section names the the class of the object to which the message was sent. The ARGS section says how many arguments were included in the message. Read the CALL STACK from the bottom to the top to see where the error happened. Reading from bottom to top means going from
62 code::
63 Process-interpretPrintCmdLine
68 code::
69 Interpreter-interpretPrintCmdLine
74 code::
75 Object-doesNotUnderstand
80 code::
81 Object-throw
86 code::
87 Nil-handleError
92 code::
93 DoesNotUnderstandError-reportError
96 which is the first line in the stack.
98 ////////////////////////////////////////////////////////////////////////////////////////////////////
100 code::
101 DoesNotUnderstandError-reportError
104 is the mechanism that prints the error notification to the post window. Select it and press cmd-j to see how it works (how it prints the notification).
106 ////////////////////////////////////////////////////////////////////////////////////////////////////
108 Execute
110 code::
111 $a * $b
114 to create another runtime error message.
116 ////////////////////////////////////////////////////////////////////////////////////////////////////
118 The ERROR, RECEIVER, ARGS, and CALL STACK headers in the post window explain the problem: Instances of class Char have no knowledge of multiplication.
120 code::
121 ERROR: Message '*' not understood.
122 RECEIVER:
123    Character 97 'a'
124 ARGS:
125 Instance of Array {    (067F5470, gc=C4, fmt=01, flg=00, set=01)
126   indexed slots [1]
127       0 : Character 98 'b'
129 CALL STACK:
130         DoesNotUnderstandError-reportError
131                 arg this = <instance of DoesNotUnderstandError>
132         Nil-handleError
133                 arg this = nil
134                 arg error = <instance of DoesNotUnderstandError>
135         Object-throw
136                 arg this = <instance of DoesNotUnderstandError>
137         Object-doesNotUnderstand
138                 arg this = $a
139                 arg selector = '*'
140                 arg args = [*1]
141         < closed FunctionDef >  (no arguments or variables)
142         Interpreter-interpretPrintCmdLine
143                 arg this = <instance of Interpreter>
144                 var res = nil
145                 var func = <instance of Function>
146         Process-interpretPrintCmdLine
147                 arg this = <instance of Main>
150 section::Unitialized variable (binary operation fails)
152 Here, the variable a is initialized to an integer and the variable b isn't initialized. Multiplying a (the integer 10) by b (nil, the value that SuperCollider uses for unitialized data) will create a runtime error.
154 code::
156 var a = 10;     // a is declared and initialized
157 var b;          // b declared but not initialized, so it defaults to nil
159 t = Task({
161         4.do({ arg item, i;
163                 if(i != 3)
164                         { i.postln }            // print the value of i if it doesn't equal 3
165                         { (a * b).postln };     // when i equals 3, do a * b
166                                                 // ... which is a problem if b is nil
167                 1.wait;
169         })
172 t.start;
176 ////////////////////////////////////////////////////////////////////////////////////////////////////
178 The printout shows the code ran successfully until the index, i, reached 3, which is when a * b happened. The ERROR, RECEIVER, ARGS, and CALL STACK headers describe the problem.
180 ////////////////////////////////////////////////////////////////////////////////////////////////////
182 code::
183 a Task
187 ERROR: binary operator '*' failed.
188 RECEIVER:
189    nil
190 ARGS:
191 Instance of Array {    (067D92B0, gc=CC, fmt=01, flg=00, set=01)
192   indexed slots [2]
193       0 : Integer 10
194       1 : nil
196 CALL STACK:
197         DoesNotUnderstandError-reportError
198                 arg this = <instance of BinaryOpFailureError>
199         Nil-handleError
200                 arg this = nil
201                 arg error = <instance of BinaryOpFailureError>
202         Object-throw
203                 arg this = <instance of BinaryOpFailureError>
204         Object-performBinaryOpOnSomething
205                 arg this = nil
206                 arg aSelector = '*'
207                 arg thing = 10
208                 arg adverb = nil
209         Integer-*
210                 arg this = 10
211                 arg aNumber = nil
212                 arg adverb = nil
213         < FunctionDef in closed FunctionDef >
214                 arg item = 3
215                 arg i = 3
216         Integer-do
217                 arg this = 4
218                 arg function = <instance of Function>
219                 var i = 3
220         < FunctionDef in closed FunctionDef >  (no arguments or variables)
221         Routine-prStart
222                 arg this = <instance of Routine>
223                 arg inval = 758.000000
226 ////////////////////////////////////////////////////////////////////////////////////////////////////
228 section::True, false, or other
230 A value other than true or false in a boolean test, as in
232 code::
233 if(x=4) { "this is ok"};
236 produces
238 code::
239 ERROR: Non Boolean in test.
240 RECEIVER:
241    Integer 4
242 CALL STACK:
243         MethodError-reportError
244                 arg this = <instance of MustBeBooleanError>
245         Nil-handleError
246                 arg this = nil
247                 arg error = <instance of MustBeBooleanError>
248         Object-throw
249                 arg this = <instance of MustBeBooleanError>
250         Object-mustBeBoolean
251                 arg this = 4
252         < closed FunctionDef >  (no arguments or variables)
253         Interpreter-interpretPrintCmdLine
254                 arg this = <instance of Interpreter>
255                 var res = nil
256                 var func = <instance of Function>
257         Process-interpretPrintCmdLine
258                 arg this = <instance of Main>
261 ////////////////////////////////////////////////////////////////////////////////////////////////////
263 Correcting the test clause fixes the problem.
265 code::
266 if(x==4) { "this is ok"};
269 ////////////////////////////////////////////////////////////////////////////////////////////////////
271 section::Primitive fails
273 Asking for the length of a non-existent file creates a runtime error. The notification shows what went wrong (a C code primitive failed).
275 code::
276 f = File("i_don't_exist", "r");
277 f.length;
279 ERROR: Primitive '_FileLength' failed.
280 Failed.
281 RECEIVER:
282 Instance of File {    (067D9970, gc=C4, fmt=00, flg=00, set=01)
283   instance variables [1]
284     fileptr : nil
286 CALL STACK:
287         MethodError-reportError
288                 arg this = <instance of PrimitiveFailedError>
289         Nil-handleError
290                 arg this = nil
291                 arg error = <instance of PrimitiveFailedError>
292         Object-throw
293                 arg this = <instance of PrimitiveFailedError>
294         Object-primitiveFailed
295                 arg this = <instance of File>
296         File-length
297                 arg this = <instance of File>
298         < closed FunctionDef >  (no arguments or variables)
299         Interpreter-interpretPrintCmdLine
300                 arg this = <instance of Interpreter>
301                 var res = nil
302                 var func = <instance of Function>
303         Process-interpretPrintCmdLine
304                 arg this = <instance of Main>
307 ////////////////////////////////////////////////////////////////////////////////////////////////////