Commit | Line | Data |
4633a7c4 |
1 | package overload; |
2 | |
a6006777 |
3 | sub nil {} |
4 | |
4633a7c4 |
5 | sub OVERLOAD { |
6 | $package = shift; |
7 | my %arg = @_; |
a6006777 |
8 | my ($sub, $fb); |
9 | $ {$package . "::OVERLOAD"}{dummy}++; # Register with magic by touching. |
10 | *{$package . "::()"} = \&nil; # Make it findable via fetchmethod. |
4633a7c4 |
11 | for (keys %arg) { |
a6006777 |
12 | if ($_ eq 'fallback') { |
13 | $fb = $arg{$_}; |
14 | } else { |
15 | $sub = $arg{$_}; |
16 | if (not ref $sub and $sub !~ /::/) { |
44a8e56a |
17 | $ {$package . "::(" . $_} = $sub; |
18 | $sub = \&nil; |
a6006777 |
19 | } |
20 | #print STDERR "Setting `$ {'package'}::\cO$_' to \\&`$sub'.\n"; |
21 | *{$package . "::(" . $_} = \&{ $sub }; |
22 | } |
4633a7c4 |
23 | } |
a6006777 |
24 | ${$package . "::()"} = $fb; # Make it findable too (fallback only). |
4633a7c4 |
25 | } |
26 | |
27 | sub import { |
28 | $package = (caller())[0]; |
29 | # *{$package . "::OVERLOAD"} = \&OVERLOAD; |
30 | shift; |
31 | $package->overload::OVERLOAD(@_); |
32 | } |
33 | |
34 | sub unimport { |
35 | $package = (caller())[0]; |
a6006777 |
36 | ${$package . "::OVERLOAD"}{dummy}++; # Upgrade the table |
4633a7c4 |
37 | shift; |
38 | for (@_) { |
a6006777 |
39 | if ($_ eq 'fallback') { |
40 | undef $ {$package . "::()"}; |
41 | } else { |
42 | delete $ {$package . "::"}{"(" . $_}; |
43 | } |
4633a7c4 |
44 | } |
45 | } |
46 | |
47 | sub Overloaded { |
a6006777 |
48 | my $package = shift; |
49 | $package = ref $package if ref $package; |
50 | $package->can('()'); |
4633a7c4 |
51 | } |
52 | |
44a8e56a |
53 | sub ov_method { |
54 | my $globref = shift; |
55 | return undef unless $globref; |
56 | my $sub = \&{*$globref}; |
57 | return $sub if $sub ne \&nil; |
58 | return shift->can($ {*$globref}); |
59 | } |
60 | |
4633a7c4 |
61 | sub OverloadedStringify { |
a6006777 |
62 | my $package = shift; |
63 | $package = ref $package if ref $package; |
44a8e56a |
64 | #$package->can('(""') |
65 | ov_method mycan($package, '(""'), $package; |
4633a7c4 |
66 | } |
67 | |
68 | sub Method { |
a6006777 |
69 | my $package = shift; |
70 | $package = ref $package if ref $package; |
44a8e56a |
71 | #my $meth = $package->can('(' . shift); |
72 | ov_method mycan($package, '(' . shift), $package; |
73 | #return $meth if $meth ne \&nil; |
74 | #return $ {*{$meth}}; |
4633a7c4 |
75 | } |
76 | |
77 | sub AddrRef { |
a6006777 |
78 | my $package = ref $_[0]; |
79 | return "$_[0]" unless $package; |
80 | bless $_[0], overload::Fake; # Non-overloaded package |
4633a7c4 |
81 | my $str = "$_[0]"; |
82 | bless $_[0], $package; # Back |
a6006777 |
83 | $package . substr $str, index $str, '='; |
4633a7c4 |
84 | } |
85 | |
86 | sub StrVal { |
a6006777 |
87 | (OverloadedStringify($_[0])) ? |
88 | (AddrRef(shift)) : |
4633a7c4 |
89 | "$_[0]"; |
90 | } |
91 | |
44a8e56a |
92 | sub mycan { # Real can would leave stubs. |
93 | my ($package, $meth) = @_; |
94 | return \*{$package . "::$meth"} if defined &{$package . "::$meth"}; |
95 | my $p; |
96 | foreach $p (@{$package . "::ISA"}) { |
97 | my $out = mycan($p, $meth); |
98 | return $out if $out; |
99 | } |
100 | return undef; |
101 | } |
102 | |
4633a7c4 |
103 | 1; |
104 | |
105 | __END__ |
106 | |
107 | =head1 NAME |
108 | |
cb1a09d0 |
109 | overload - Package for overloading perl operations |
4633a7c4 |
110 | |
111 | =head1 SYNOPSIS |
112 | |
113 | package SomeThing; |
114 | |
115 | use overload |
116 | '+' => \&myadd, |
117 | '-' => \&mysub; |
118 | # etc |
119 | ... |
120 | |
121 | package main; |
122 | $a = new SomeThing 57; |
123 | $b=5+$a; |
124 | ... |
125 | if (overload::Overloaded $b) {...} |
126 | ... |
127 | $strval = overload::StrVal $b; |
128 | |
129 | =head1 CAVEAT SCRIPTOR |
130 | |
131 | Overloading of operators is a subject not to be taken lightly. |
132 | Neither its precise implementation, syntax, nor semantics are |
133 | 100% endorsed by Larry Wall. So any of these may be changed |
134 | at some point in the future. |
135 | |
136 | =head1 DESCRIPTION |
137 | |
138 | =head2 Declaration of overloaded functions |
139 | |
140 | The compilation directive |
141 | |
142 | package Number; |
143 | use overload |
144 | "+" => \&add, |
145 | "*=" => "muas"; |
146 | |
147 | declares function Number::add() for addition, and method muas() in |
148 | the "class" C<Number> (or one of its base classes) |
149 | for the assignment form C<*=> of multiplication. |
150 | |
151 | Arguments of this directive come in (key, value) pairs. Legal values |
e7ea3e70 |
152 | are values legal inside a C<&{ ... }> call, so the name of a |
153 | subroutine, a reference to a subroutine, or an anonymous subroutine |
154 | will all work. Note that values specified as strings are |
155 | interpreted as methods, not subroutines. Legal keys are listed below. |
4633a7c4 |
156 | |
157 | The subroutine C<add> will be called to execute C<$a+$b> if $a |
158 | is a reference to an object blessed into the package C<Number>, or if $a is |
159 | not an object from a package with defined mathemagic addition, but $b is a |
160 | reference to a C<Number>. It can also be called in other situations, like |
161 | C<$a+=7>, or C<$a++>. See L<MAGIC AUTOGENERATION>. (Mathemagical |
162 | methods refer to methods triggered by an overloaded mathematical |
163 | operator.) |
164 | |
774d564b |
165 | Since overloading respects inheritance via the @ISA hierarchy, the |
166 | above declaration would also trigger overloading of C<+> and C<*=> in |
167 | all the packages which inherit from C<Number>. |
e7ea3e70 |
168 | |
4633a7c4 |
169 | =head2 Calling Conventions for Binary Operations |
170 | |
171 | The functions specified in the C<use overload ...> directive are called |
172 | with three (in one particular case with four, see L<Last Resort>) |
173 | arguments. If the corresponding operation is binary, then the first |
174 | two arguments are the two arguments of the operation. However, due to |
175 | general object calling conventions, the first argument should always be |
176 | an object in the package, so in the situation of C<7+$a>, the |
177 | order of the arguments is interchanged. It probably does not matter |
178 | when implementing the addition method, but whether the arguments |
179 | are reversed is vital to the subtraction method. The method can |
180 | query this information by examining the third argument, which can take |
181 | three different values: |
182 | |
183 | =over 7 |
184 | |
185 | =item FALSE |
186 | |
187 | the order of arguments is as in the current operation. |
188 | |
189 | =item TRUE |
190 | |
191 | the arguments are reversed. |
192 | |
193 | =item C<undef> |
194 | |
195 | the current operation is an assignment variant (as in |
196 | C<$a+=7>), but the usual function is called instead. This additional |
197 | information can be used to generate some optimizations. |
198 | |
199 | =back |
200 | |
201 | =head2 Calling Conventions for Unary Operations |
202 | |
203 | Unary operation are considered binary operations with the second |
204 | argument being C<undef>. Thus the functions that overloads C<{"++"}> |
205 | is called with arguments C<($a,undef,'')> when $a++ is executed. |
206 | |
207 | =head2 Overloadable Operations |
208 | |
209 | The following symbols can be specified in C<use overload>: |
210 | |
211 | =over 5 |
212 | |
213 | =item * I<Arithmetic operations> |
214 | |
215 | "+", "+=", "-", "-=", "*", "*=", "/", "/=", "%", "%=", |
216 | "**", "**=", "<<", "<<=", ">>", ">>=", "x", "x=", ".", ".=", |
217 | |
218 | For these operations a substituted non-assignment variant can be called if |
219 | the assignment variant is not available. Methods for operations "C<+>", |
220 | "C<->", "C<+=>", and "C<-=>" can be called to automatically generate |
221 | increment and decrement methods. The operation "C<->" can be used to |
222 | autogenerate missing methods for unary minus or C<abs>. |
223 | |
224 | =item * I<Comparison operations> |
225 | |
226 | "<", "<=", ">", ">=", "==", "!=", "<=>", |
227 | "lt", "le", "gt", "ge", "eq", "ne", "cmp", |
228 | |
229 | If the corresponding "spaceship" variant is available, it can be |
230 | used to substitute for the missing operation. During C<sort>ing |
231 | arrays, C<cmp> is used to compare values subject to C<use overload>. |
232 | |
233 | =item * I<Bit operations> |
234 | |
235 | "&", "^", "|", "neg", "!", "~", |
236 | |
237 | "C<neg>" stands for unary minus. If the method for C<neg> is not |
3bc6ec80 |
238 | specified, it can be autogenerated using the method for |
239 | subtraction. If the method for "C<!>" is not specified, it can be |
240 | autogenerated using the methods for "C<bool>", or "C<\"\">", or "C<0+>". |
4633a7c4 |
241 | |
242 | =item * I<Increment and decrement> |
243 | |
244 | "++", "--", |
245 | |
246 | If undefined, addition and subtraction methods can be |
247 | used instead. These operations are called both in prefix and |
248 | postfix form. |
249 | |
250 | =item * I<Transcendental functions> |
251 | |
252 | "atan2", "cos", "sin", "exp", "abs", "log", "sqrt", |
253 | |
254 | If C<abs> is unavailable, it can be autogenerated using methods |
1fef88e7 |
255 | for "E<lt>" or "E<lt>=E<gt>" combined with either unary minus or subtraction. |
4633a7c4 |
256 | |
257 | =item * I<Boolean, string and numeric conversion> |
258 | |
259 | "bool", "\"\"", "0+", |
260 | |
261 | If one or two of these operations are unavailable, the remaining ones can |
262 | be used instead. C<bool> is used in the flow control operators |
263 | (like C<while>) and for the ternary "C<?:>" operation. These functions can |
264 | return any arbitrary Perl value. If the corresponding operation for this value |
265 | is overloaded too, that operation will be called again with this value. |
266 | |
267 | =item * I<Special> |
268 | |
269 | "nomethod", "fallback", "=", |
270 | |
271 | see L<SPECIAL SYMBOLS FOR C<use overload>>. |
272 | |
273 | =back |
274 | |
275 | See L<"Fallback"> for an explanation of when a missing method can be autogenerated. |
276 | |
e7ea3e70 |
277 | =head2 Inheritance and overloading |
278 | |
774d564b |
279 | Inheritance interacts with overloading in two ways. |
e7ea3e70 |
280 | |
281 | =over |
282 | |
283 | =item Strings as values of C<use overload> directive |
284 | |
774d564b |
285 | If C<value> in |
e7ea3e70 |
286 | |
287 | use overload key => value; |
288 | |
774d564b |
289 | is a string, it is interpreted as a method name. |
e7ea3e70 |
290 | |
291 | =item Overloading of an operation is inherited by derived classes |
292 | |
774d564b |
293 | Any class derived from an overloaded class is also overloaded. The |
294 | set of overloaded methods is the union of overloaded methods of all |
295 | the ancestors. If some method is overloaded in several ancestor, then |
e7ea3e70 |
296 | which description will be used is decided by the usual inheritance |
774d564b |
297 | rules: |
e7ea3e70 |
298 | |
774d564b |
299 | If C<A> inherits from C<B> and C<C> (in this order), C<B> overloads |
300 | C<+> with C<\&D::plus_sub>, and C<C> overloads C<+> by C<"plus_meth">, |
301 | then the subroutine C<D::plus_sub> will be called to implement |
302 | operation C<+> for an object in package C<A>. |
e7ea3e70 |
303 | |
304 | =back |
305 | |
774d564b |
306 | Note that since the value of the C<fallback> key is not a subroutine, |
307 | its inheritance is not governed by the above rules. In the current |
308 | implementation, the value of C<fallback> in the first overloaded |
309 | ancestor is used, but this is accidental and subject to change. |
e7ea3e70 |
310 | |
4633a7c4 |
311 | =head1 SPECIAL SYMBOLS FOR C<use overload> |
312 | |
313 | Three keys are recognized by Perl that are not covered by the above |
314 | description. |
315 | |
774d564b |
316 | =head2 Last Resort |
4633a7c4 |
317 | |
318 | C<"nomethod"> should be followed by a reference to a function of four |
319 | parameters. If defined, it is called when the overloading mechanism |
320 | cannot find a method for some operation. The first three arguments of |
321 | this function coincide with the arguments for the corresponding method if |
322 | it were found, the fourth argument is the symbol |
323 | corresponding to the missing method. If several methods are tried, |
324 | the last one is used. Say, C<1-$a> can be equivalent to |
325 | |
326 | &nomethodMethod($a,1,1,"-") |
327 | |
328 | if the pair C<"nomethod" =E<gt> "nomethodMethod"> was specified in the |
329 | C<use overload> directive. |
330 | |
331 | If some operation cannot be resolved, and there is no function |
332 | assigned to C<"nomethod">, then an exception will be raised via die()-- |
333 | unless C<"fallback"> was specified as a key in C<use overload> directive. |
334 | |
335 | =head2 Fallback |
336 | |
337 | The key C<"fallback"> governs what to do if a method for a particular |
338 | operation is not found. Three different cases are possible depending on |
339 | the value of C<"fallback">: |
340 | |
341 | =over 16 |
342 | |
343 | =item * C<undef> |
344 | |
345 | Perl tries to use a |
346 | substituted method (see L<MAGIC AUTOGENERATION>). If this fails, it |
347 | then tries to calls C<"nomethod"> value; if missing, an exception |
348 | will be raised. |
349 | |
350 | =item * TRUE |
351 | |
352 | The same as for the C<undef> value, but no exception is raised. Instead, |
353 | it silently reverts to what it would have done were there no C<use overload> |
354 | present. |
355 | |
356 | =item * defined, but FALSE |
357 | |
358 | No autogeneration is tried. Perl tries to call |
359 | C<"nomethod"> value, and if this is missing, raises an exception. |
360 | |
361 | =back |
362 | |
e7ea3e70 |
363 | B<Note.> C<"fallback"> inheritance via @ISA is not carved in stone |
364 | yet, see L<"Inheritance and overloading">. |
365 | |
4633a7c4 |
366 | =head2 Copy Constructor |
367 | |
368 | The value for C<"="> is a reference to a function with three |
369 | arguments, i.e., it looks like the other values in C<use |
370 | overload>. However, it does not overload the Perl assignment |
371 | operator. This would go against Camel hair. |
372 | |
373 | This operation is called in the situations when a mutator is applied |
374 | to a reference that shares its object with some other reference, such |
375 | as |
376 | |
377 | $a=$b; |
378 | $a++; |
379 | |
380 | To make this change $a and not change $b, a copy of C<$$a> is made, |
381 | and $a is assigned a reference to this new object. This operation is |
382 | done during execution of the C<$a++>, and not during the assignment, |
383 | (so before the increment C<$$a> coincides with C<$$b>). This is only |
384 | done if C<++> is expressed via a method for C<'++'> or C<'+='>. Note |
385 | that if this operation is expressed via C<'+'> a nonmutator, i.e., as |
386 | in |
387 | |
388 | $a=$b; |
389 | $a=$a+1; |
390 | |
391 | then C<$a> does not reference a new copy of C<$$a>, since $$a does not |
392 | appear as lvalue when the above code is executed. |
393 | |
394 | If the copy constructor is required during the execution of some mutator, |
395 | but a method for C<'='> was not specified, it can be autogenerated as a |
396 | string copy if the object is a plain scalar. |
397 | |
398 | =over 5 |
399 | |
400 | =item B<Example> |
401 | |
402 | The actually executed code for |
403 | |
404 | $a=$b; |
405 | Something else which does not modify $a or $b.... |
406 | ++$a; |
407 | |
408 | may be |
409 | |
410 | $a=$b; |
411 | Something else which does not modify $a or $b.... |
412 | $a = $a->clone(undef,""); |
413 | $a->incr(undef,""); |
414 | |
415 | if $b was mathemagical, and C<'++'> was overloaded with C<\&incr>, |
416 | C<'='> was overloaded with C<\&clone>. |
417 | |
418 | =back |
419 | |
420 | =head1 MAGIC AUTOGENERATION |
421 | |
422 | If a method for an operation is not found, and the value for C<"fallback"> is |
423 | TRUE or undefined, Perl tries to autogenerate a substitute method for |
424 | the missing operation based on the defined operations. Autogenerated method |
425 | substitutions are possible for the following operations: |
426 | |
427 | =over 16 |
428 | |
429 | =item I<Assignment forms of arithmetic operations> |
430 | |
431 | C<$a+=$b> can use the method for C<"+"> if the method for C<"+="> |
432 | is not defined. |
433 | |
434 | =item I<Conversion operations> |
435 | |
436 | String, numeric, and boolean conversion are calculated in terms of one |
437 | another if not all of them are defined. |
438 | |
439 | =item I<Increment and decrement> |
440 | |
441 | The C<++$a> operation can be expressed in terms of C<$a+=1> or C<$a+1>, |
442 | and C<$a--> in terms of C<$a-=1> and C<$a-1>. |
443 | |
444 | =item C<abs($a)> |
445 | |
446 | can be expressed in terms of C<$aE<lt>0> and C<-$a> (or C<0-$a>). |
447 | |
448 | =item I<Unary minus> |
449 | |
450 | can be expressed in terms of subtraction. |
451 | |
3bc6ec80 |
452 | =item I<Negation> |
453 | |
454 | C<!> and C<not> can be expressed in terms of boolean conversion, or |
455 | string or numerical conversion. |
456 | |
4633a7c4 |
457 | =item I<Concatenation> |
458 | |
459 | can be expressed in terms of string conversion. |
460 | |
461 | =item I<Comparison operations> |
462 | |
463 | can be expressed in terms of its "spaceship" counterpart: either |
464 | C<E<lt>=E<gt>> or C<cmp>: |
1fef88e7 |
465 | |
4633a7c4 |
466 | <, >, <=, >=, ==, != in terms of <=> |
467 | lt, gt, le, ge, eq, ne in terms of cmp |
468 | |
469 | =item I<Copy operator> |
470 | |
471 | can be expressed in terms of an assignment to the dereferenced value, if this |
472 | value is a scalar and not a reference. |
473 | |
474 | =back |
475 | |
476 | =head1 WARNING |
477 | |
478 | The restriction for the comparison operation is that even if, for example, |
479 | `C<cmp>' should return a blessed reference, the autogenerated `C<lt>' |
480 | function will produce only a standard logical value based on the |
481 | numerical value of the result of `C<cmp>'. In particular, a working |
482 | numeric conversion is needed in this case (possibly expressed in terms of |
483 | other conversions). |
484 | |
485 | Similarly, C<.=> and C<x=> operators lose their mathemagical properties |
486 | if the string conversion substitution is applied. |
487 | |
488 | When you chop() a mathemagical object it is promoted to a string and its |
489 | mathemagical properties are lost. The same can happen with other |
490 | operations as well. |
491 | |
492 | =head1 Run-time Overloading |
493 | |
494 | Since all C<use> directives are executed at compile-time, the only way to |
495 | change overloading during run-time is to |
496 | |
497 | eval 'use overload "+" => \&addmethod'; |
498 | |
499 | You can also use |
500 | |
501 | eval 'no overload "+", "--", "<="'; |
502 | |
503 | though the use of these constructs during run-time is questionable. |
504 | |
505 | =head1 Public functions |
506 | |
507 | Package C<overload.pm> provides the following public functions: |
508 | |
509 | =over 5 |
510 | |
511 | =item overload::StrVal(arg) |
512 | |
513 | Gives string value of C<arg> as in absence of stringify overloading. |
514 | |
515 | =item overload::Overloaded(arg) |
516 | |
517 | Returns true if C<arg> is subject to overloading of some operations. |
518 | |
519 | =item overload::Method(obj,op) |
520 | |
521 | Returns C<undef> or a reference to the method that implements C<op>. |
522 | |
523 | =back |
524 | |
525 | =head1 IMPLEMENTATION |
526 | |
527 | What follows is subject to change RSN. |
528 | |
e7ea3e70 |
529 | The table of methods for all operations is cached in magic for the |
530 | symbol table hash for the package. The cache is invalidated during |
531 | processing of C<use overload>, C<no overload>, new function |
532 | definitions, and changes in @ISA. However, this invalidation remains |
533 | unprocessed until the next C<bless>ing into the package. Hence if you |
534 | want to change overloading structure dynamically, you'll need an |
535 | additional (fake) C<bless>ing to update the table. |
536 | |
537 | (Every SVish thing has a magic queue, and magic is an entry in that |
538 | queue. This is how a single variable may participate in multiple |
539 | forms of magic simultaneously. For instance, environment variables |
540 | regularly have two forms at once: their %ENV magic and their taint |
541 | magic. However, the magic which implements overloading is applied to |
542 | the stashes, which are rarely used directly, thus should not slow down |
543 | Perl.) |
4633a7c4 |
544 | |
545 | If an object belongs to a package using overload, it carries a special |
546 | flag. Thus the only speed penalty during arithmetic operations without |
547 | overloading is the checking of this flag. |
548 | |
774d564b |
549 | In fact, if C<use overload> is not present, there is almost no overhead |
550 | for overloadable operations, so most programs should not suffer |
551 | measurable performance penalties. A considerable effort was made to |
552 | minimize the overhead when overload is used in some package, but the |
553 | arguments in question do not belong to packages using overload. When |
554 | in doubt, test your speed with C<use overload> and without it. So far |
555 | there have been no reports of substantial speed degradation if Perl is |
556 | compiled with optimization turned on. |
4633a7c4 |
557 | |
e7ea3e70 |
558 | There is no size penalty for data if overload is not used. The only |
559 | size penalty if overload is used in some package is that I<all> the |
560 | packages acquire a magic during the next C<bless>ing into the |
561 | package. This magic is three-words-long for packages without |
562 | overloading, and carries the cache tabel if the package is overloaded. |
4633a7c4 |
563 | |
564 | Copying (C<$a=$b>) is shallow; however, a one-level-deep copying is |
565 | carried out before any operation that can imply an assignment to the |
566 | object $a (or $b) refers to, like C<$a++>. You can override this |
567 | behavior by defining your own copy constructor (see L<"Copy Constructor">). |
568 | |
569 | It is expected that arguments to methods that are not explicitly supposed |
570 | to be changed are constant (but this is not enforced). |
571 | |
572 | =head1 AUTHOR |
573 | |
1fef88e7 |
574 | Ilya Zakharevich E<lt>F<ilya@math.mps.ohio-state.edu>E<gt>. |
4633a7c4 |
575 | |
576 | =head1 DIAGNOSTICS |
577 | |
578 | When Perl is run with the B<-Do> switch or its equivalent, overloading |
579 | induces diagnostic messages. |
580 | |
e7ea3e70 |
581 | Using the C<m> command of Perl debugger (see L<perldebug>) one can |
582 | deduce which operations are overloaded (and which ancestor triggers |
583 | this overloading). Say, if C<eq> is overloaded, then the method C<(eq> |
584 | is shown by debugger. The method C<()> corresponds to the C<fallback> |
585 | key (in fact a presence of this method shows that this package has |
586 | overloading enabled, and it is what is used by the C<Overloaded> |
587 | function). |
588 | |
4633a7c4 |
589 | =head1 BUGS |
590 | |
aa689395 |
591 | Because it is used for overloading, the per-package hash %OVERLOAD now |
592 | has a special meaning in Perl. The symbol table is filled with names |
593 | looking like line-noise. |
4633a7c4 |
594 | |
a6006777 |
595 | For the purpose of inheritance every overloaded package behaves as if |
596 | C<fallback> is present (possibly undefined). This may create |
597 | interesting effects if some package is not overloaded, but inherits |
598 | from two overloaded packages. |
4633a7c4 |
599 | |
600 | This document is confusing. |
601 | |
602 | =cut |
603 | |