This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
new perldelta
[perl5.git] / lib / overload.t
... / ...
CommitLineData
1#!./perl -T
2
3BEGIN {
4 chdir 't' if -d 't';
5 @INC = '../lib';
6 require Config;
7 if (($Config::Config{'extensions'} !~ m!\bList/Util\b!) ){
8 print "1..0 # Skip -- Perl configured without List::Util module\n";
9 exit 0;
10 }
11}
12
13my $no_taint_support = exists($Config::Config{taint_support})
14 && !$Config::Config{taint_support};
15
16my %skip_fetch_count_when_no_taint = (
17 '<${$ts}> RT57012_OV' => 1,
18 '<use integer; ${$ts}> RT57012_OV' => 1,
19 '<do {&{$ts} for 1,2}> RT57012_OV' => 1,
20 '<use integer; do {&{$ts} for 1,2}> RT57012_OV' => 1,
21 '<*RT57012B = *{$ts}; our $RT57012B> RT57012_OV' => 1,
22 '<use integer; *RT57012B = *{$ts}; our $RT57012B> RT57012_OV' => 1,
23);
24
25sub is_if_taint_supported {
26 my ($got, $expected, $name, @mess) = @_;
27 if ($expected && $no_taint_support) {
28 return skip("your perl was built without taint support");
29 }
30 else {
31 return is($got, $expected, $name, @mess);
32 }
33}
34
35
36package Oscalar;
37use overload (
38 # Anonymous subroutines:
39'+' => sub {new Oscalar $ {$_[0]}+$_[1]},
40'-' => sub {new Oscalar
41 $_[2]? $_[1]-${$_[0]} : ${$_[0]}-$_[1]},
42'<=>' => sub {new Oscalar
43 $_[2]? $_[1]-${$_[0]} : ${$_[0]}-$_[1]},
44'cmp' => sub {new Oscalar
45 $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
46'*' => sub {new Oscalar ${$_[0]}*$_[1]},
47'/' => sub {new Oscalar
48 $_[2]? $_[1]/${$_[0]} :
49 ${$_[0]}/$_[1]},
50'%' => sub {new Oscalar
51 $_[2]? $_[1]%${$_[0]} : ${$_[0]}%$_[1]},
52'**' => sub {new Oscalar
53 $_[2]? $_[1]**${$_[0]} : ${$_[0]}-$_[1]},
54
55qw(
56"" stringify
570+ numify) # Order of arguments insignificant
58);
59
60sub new {
61 my $foo = $_[1];
62 bless \$foo, $_[0];
63}
64
65sub stringify { "${$_[0]}" }
66sub numify { 0 + "${$_[0]}" } # Not needed, additional overhead
67 # comparing to direct compilation based on
68 # stringify
69
70package main;
71
72$| = 1;
73BEGIN { require './test.pl'; require './charset_tools.pl' }
74plan tests => 5367;
75
76use Scalar::Util qw(tainted);
77
78$a = new Oscalar "087";
79$b= "$a";
80
81is($b, $a);
82is($b, "087");
83is(ref $a, "Oscalar");
84is($a, $a);
85is($a, "087");
86
87$c = $a + 7;
88
89is(ref $c, "Oscalar");
90isnt($c, $a);
91is($c, "94");
92
93$b=$a;
94
95is(ref $a, "Oscalar");
96
97$b++;
98
99is(ref $b, "Oscalar");
100is($a, "087");
101is($b, "88");
102is(ref $a, "Oscalar");
103
104$c=$b;
105$c-=$a;
106
107is(ref $c, "Oscalar");
108is($a, "087");
109is($c, "1");
110is(ref $a, "Oscalar");
111
112$b=1;
113$b+=$a;
114
115is(ref $b, "Oscalar");
116is($a, "087");
117is($b, "88");
118is(ref $a, "Oscalar");
119
120eval q[ package Oscalar; use overload ('++' => sub { $ {$_[0]}++;$_[0] } ) ];
121
122$b=$a;
123
124is(ref $a, "Oscalar");
125
126$b++;
127
128is(ref $b, "Oscalar");
129is($a, "087");
130is($b, "88");
131is(ref $a, "Oscalar");
132
133package Oscalar;
134$dummy=bless \$dummy; # Now cache of method should be reloaded
135package main;
136
137$b=$a;
138$b++;
139
140is(ref $b, "Oscalar");
141is($a, "087");
142is($b, "88");
143is(ref $a, "Oscalar");
144
145undef $b; # Destroying updates tables too...
146
147eval q[package Oscalar; use overload ('++' => sub { $ {$_[0]} += 2; $_[0] } ) ];
148
149$b=$a;
150
151is(ref $a, "Oscalar");
152
153$b++;
154
155is(ref $b, "Oscalar");
156is($a, "087");
157is($b, "89");
158is(ref $a, "Oscalar");
159
160package Oscalar;
161$dummy=bless \$dummy; # Now cache of method should be reloaded
162package main;
163
164$b++;
165
166is(ref $b, "Oscalar");
167is($a, "087");
168is($b, "91");
169is(ref $a, "Oscalar");
170
171$b=$a;
172$b++;
173
174is(ref $b, "Oscalar");
175is($a, "087");
176is($b, "89");
177is(ref $a, "Oscalar");
178
179
180ok($b? 1:0);
181
182eval q[ package Oscalar; use overload ('=' => sub {$main::copies++;
183 package Oscalar;
184 local $new=$ {$_[0]};
185 bless \$new } ) ];
186
187$b=new Oscalar "$a";
188
189is(ref $b, "Oscalar");
190is($a, "087");
191is($b, "087");
192is(ref $a, "Oscalar");
193
194$b++;
195
196is(ref $b, "Oscalar");
197is($a, "087");
198is($b, "89");
199is(ref $a, "Oscalar");
200is($copies, undef);
201
202$b+=1;
203
204is(ref $b, "Oscalar");
205is($a, "087");
206is($b, "90");
207is(ref $a, "Oscalar");
208is($copies, undef);
209
210$b=$a;
211$b+=1;
212
213is(ref $b, "Oscalar");
214is($a, "087");
215is($b, "88");
216is(ref $a, "Oscalar");
217is($copies, undef);
218
219$b=$a;
220$b++;
221
222is(ref $b, "Oscalar");
223is($a, "087");
224is($b, "89");
225is(ref $a, "Oscalar");
226is($copies, 1);
227
228eval q[package Oscalar; use overload ('+=' => sub {$ {$_[0]} += 3*$_[1];
229 $_[0] } ) ];
230$c=new Oscalar; # Cause rehash
231
232$b=$a;
233$b+=1;
234
235is(ref $b, "Oscalar");
236is($a, "087");
237is($b, "90");
238is(ref $a, "Oscalar");
239is($copies, 2);
240
241$b+=$b;
242
243is(ref $b, "Oscalar");
244is($b, "360");
245is($copies, 2);
246$b=-$b;
247
248is(ref $b, "Oscalar");
249is($b, "-360");
250is($copies, 2);
251
252$b=abs($b);
253
254is(ref $b, "Oscalar");
255is($b, "360");
256is($copies, 2);
257
258$b=abs($b);
259
260is(ref $b, "Oscalar");
261is($b, "360");
262is($copies, 2);
263
264eval q[package Oscalar;
265 use overload ('x' => sub {new Oscalar ( $_[2] ? "_.$_[1]._" x $ {$_[0]}
266 : "_.${$_[0]}._" x $_[1])}) ];
267
268$a=new Oscalar "yy";
269$a x= 3;
270is($a, "_.yy.__.yy.__.yy._");
271
272eval q[package Oscalar;
273 use overload ('.' => sub {new Oscalar ( $_[2] ?
274 "_.$_[1].__.$ {$_[0]}._"
275 : "_.$ {$_[0]}.__.$_[1]._")}) ];
276
277$a=new Oscalar "xx";
278
279is("b${a}c", "_._.b.__.xx._.__.c._");
280
281# Check inheritance of overloading;
282{
283 package OscalarI;
284 @ISA = 'Oscalar';
285}
286
287$aI = new OscalarI "$a";
288is(ref $aI, "OscalarI");
289is("$aI", "xx");
290is($aI, "xx");
291is("b${aI}c", "_._.b.__.xx._.__.c._");
292
293# Here we test that both "no overload" and
294# blessing to a package update hash
295
296eval "package Oscalar; no overload '.'";
297
298is("b${a}", "bxx");
299$x="1";
300bless \$x, Oscalar;
301is("b${a}c", "bxxc");
302new Oscalar 1;
303is("b${a}c", "bxxc");
304
305# Negative overloading:
306
307$na = eval { ~$a };
308like($@, qr/no method found/);
309
310# Check AUTOLOADING:
311
312*Oscalar::AUTOLOAD =
313 sub { *{"Oscalar::$AUTOLOAD"} = sub {"_!_" . shift() . "_!_"} ;
314 goto &{"Oscalar::$AUTOLOAD"}};
315
316eval "package Oscalar; sub comple; use overload '~' => 'comple'";
317
318$na = eval { ~$a };
319is($@, '');
320
321bless \$x, Oscalar;
322
323$na = eval { ~$a }; # Hash updated
324warn "'$na', $@" if $@;
325ok !$@;
326is($na, '_!_xx_!_');
327
328$na = 0;
329
330$na = eval { ~$aI };
331is($@, '');
332
333bless \$x, OscalarI;
334
335$na = eval { ~$aI };
336print $@;
337
338ok(!$@);
339is($na, '_!_xx_!_');
340
341eval "package Oscalar; sub rshft; use overload '>>' => 'rshft'";
342
343$na = eval { $aI >> 1 };
344is($@, '');
345
346bless \$x, OscalarI;
347
348$na = 0;
349
350$na = eval { $aI >> 1 };
351print $@;
352
353ok(!$@);
354is($na, '_!_xx_!_');
355
356# warn overload::Method($a, '0+'), "\n";
357is(overload::Method($a, '0+'), \&Oscalar::numify);
358is(overload::Method($aI,'0+'), \&Oscalar::numify);
359ok(overload::Overloaded($aI));
360ok(!overload::Overloaded('overload'));
361
362ok(! defined overload::Method($aI, '<<'));
363ok(! defined overload::Method($a, '<'));
364
365like (overload::StrVal($aI), qr/^OscalarI=SCALAR\(0x[\da-fA-F]+\)$/);
366is(overload::StrVal(\$aI), "@{[\$aI]}");
367
368# Check overloading by methods (specified deep in the ISA tree).
369{
370 package OscalarII;
371 @ISA = 'OscalarI';
372 sub Oscalar::lshft {"_<<_" . shift() . "_<<_"}
373 eval "package OscalarI; use overload '<<' => 'lshft', '|' => 'lshft'";
374}
375
376$aaII = "087";
377$aII = \$aaII;
378bless $aII, 'OscalarII';
379bless \$fake, 'OscalarI'; # update the hash
380is(($aI | 3), '_<<_xx_<<_');
381# warn $aII << 3;
382is(($aII << 3), '_<<_087_<<_');
383
384{
385 BEGIN { $int = 7; overload::constant 'integer' => sub {$int++; shift}; }
386 $out = 2**10;
387}
388is($int, 9);
389is($out, 1024);
390is($int, 9);
391{
392 BEGIN { overload::constant 'integer' => sub {$int++; shift()+1}; }
393 eval q{$out = 42};
394}
395is($int, 10);
396is($out, 43);
397
398$foo = 'foo';
399$foo1 = 'f\'o\\o';
400{
401 BEGIN { $q = $qr = 7;
402 overload::constant 'q' => sub {$q++; push @q, shift, ($_[1] || 'none'); shift},
403 'qr' => sub {$qr++; push @qr, shift, ($_[1] || 'none'); shift}; }
404 $out = 'foo';
405 $out1 = 'f\'o\\o';
406 $out2 = "a\a$foo,\,";
407 /b\b$foo.\./;
408}
409
410is($out, 'foo');
411is($out, $foo);
412is($out1, 'f\'o\\o');
413is($out1, $foo1);
414is($out2, "a\afoo,\,");
415is("@q", "foo q f'o\\\\o q a\\a qq ,\\, qq");
416is($q, 11);
417is("@qr", "b\\b qq .\\. qq");
418is($qr, 9);
419
420{
421 $_ = '!<b>!foo!<-.>!';
422 BEGIN { overload::constant 'q' => sub {push @q1, shift, ($_[1] || 'none'); "_<" . (shift) . ">_"},
423 'qr' => sub {push @qr1, shift, ($_[1] || 'none'); "!<" . (shift) . ">!"}; }
424 $out = 'foo';
425 $out1 = 'f\'o\\o';
426 $out2 = "a\a$foo,\,";
427 $res = /b\b$foo.\./;
428 $a = <<EOF;
429oups
430EOF
431 $b = <<'EOF';
432oups1
433EOF
434 $c = bareword;
435 m'try it';
436 s'first part'second part';
437 s/yet another/tail here/;
438 tr/A-Z/a-z/;
439}
440
441is($out, '_<foo>_');
442is($out1, '_<f\'o\\o>_');
443is($out2, "_<a\a>_foo_<,\,>_");
444is("@q1", "foo q f'o\\\\o q a\\a qq ,\\, qq oups
445 qq oups1
446 q second part q tail here s A-Z tr a-z tr");
447is("@qr1", "b\\b qq .\\. qq try it q first part q yet another qq");
448is($res, 1);
449is($a, "_<oups
450>_");
451is($b, "_<oups1
452>_");
453is($c, "bareword");
454
455{
456 package symbolic; # Primitive symbolic calculator
457 use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num,
458 '=' => \&cpy, '++' => \&inc, '--' => \&dec;
459
460 sub new { shift; bless ['n', @_] }
461 sub cpy {
462 my $self = shift;
463 bless [@$self], ref $self;
464 }
465 sub inc { $_[0] = bless ['++', $_[0], 1]; }
466 sub dec { $_[0] = bless ['--', $_[0], 1]; }
467 sub wrap {
468 my ($obj, $other, $inv, $meth) = @_;
469 if ($meth eq '++' or $meth eq '--') {
470 @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference
471 return $obj;
472 }
473 ($obj, $other) = ($other, $obj) if $inv;
474 bless [$meth, $obj, $other];
475 }
476 sub str {
477 my ($meth, $a, $b) = @{+shift};
478 $a = 'u' unless defined $a;
479 if (defined $b) {
480 "[$meth $a $b]";
481 } else {
482 "[$meth $a]";
483 }
484 }
485 my %subr = ( 'n' => sub {$_[0]} );
486 foreach my $op (split " ", $overload::ops{with_assign}) {
487 $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}";
488 }
489 my @bins = qw(binary 3way_comparison num_comparison str_comparison);
490 foreach my $op (split " ", "@overload::ops{ @bins }") {
491 $subr{$op} = eval "sub {shift() $op shift()}";
492 }
493 foreach my $op (split " ", "@overload::ops{qw(unary func)}") {
494 $subr{$op} = eval "sub {$op shift()}";
495 }
496 $subr{'++'} = $subr{'+'};
497 $subr{'--'} = $subr{'-'};
498
499 sub num {
500 my ($meth, $a, $b) = @{+shift};
501 my $subr = $subr{$meth}
502 or die "Do not know how to ($meth) in symbolic";
503 $a = $a->num if ref $a eq __PACKAGE__;
504 $b = $b->num if ref $b eq __PACKAGE__;
505 $subr->($a,$b);
506 }
507 sub TIESCALAR { my $pack = shift; $pack->new(@_) }
508 sub FETCH { shift }
509 sub nop { } # Around a bug
510 sub vars { my $p = shift; tie($_, $p), $_->nop foreach @_; }
511 sub STORE {
512 my $obj = shift;
513 $#$obj = 1;
514 $obj->[1] = shift;
515 }
516}
517
518{
519 my $foo = new symbolic 11;
520 my $baz = $foo++;
521 is((sprintf "%d", $foo), '12');
522 is((sprintf "%d", $baz), '11');
523 my $bar = $foo;
524 $baz = ++$foo;
525 is((sprintf "%d", $foo), '13');
526 is((sprintf "%d", $bar), '12');
527 is((sprintf "%d", $baz), '13');
528 my $ban = $foo;
529 $baz = ($foo += 1);
530 is((sprintf "%d", $foo), '14');
531 is((sprintf "%d", $bar), '12');
532 is((sprintf "%d", $baz), '14');
533 is((sprintf "%d", $ban), '13');
534 $baz = 0;
535 $baz = $foo++;
536 is((sprintf "%d", $foo), '15');
537 is((sprintf "%d", $baz), '14');
538 is("$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]');
539}
540
541{
542 my $iter = new symbolic 2;
543 my $side = new symbolic 1;
544 my $cnt = $iter;
545
546 while ($cnt) {
547 $cnt = $cnt - 1; # The "simple" way
548 $side = (sqrt(1 + $side**2) - 1)/$side;
549 }
550 my $pi = $side*(2**($iter+2));
551 is("$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]');
552 is((sprintf "%f", $pi), '3.182598');
553}
554
555{
556 my $iter = new symbolic 2;
557 my $side = new symbolic 1;
558 my $cnt = $iter;
559
560 while ($cnt--) {
561 $side = (sqrt(1 + $side**2) - 1)/$side;
562 }
563 my $pi = $side*(2**($iter+2));
564 is("$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]');
565 is((sprintf "%f", $pi), '3.182598');
566}
567
568{
569 my ($a, $b);
570 symbolic->vars($a, $b);
571 my $c = sqrt($a**2 + $b**2);
572 $a = 3; $b = 4;
573 is((sprintf "%d", $c), '5');
574 $a = 12; $b = 5;
575 is((sprintf "%d", $c), '13');
576}
577
578{
579 package symbolic1; # Primitive symbolic calculator
580 # Mutator inc/dec
581 use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num, '=' => \&cpy;
582
583 sub new { shift; bless ['n', @_] }
584 sub cpy {
585 my $self = shift;
586 bless [@$self], ref $self;
587 }
588 sub wrap {
589 my ($obj, $other, $inv, $meth) = @_;
590 if ($meth eq '++' or $meth eq '--') {
591 @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference
592 return $obj;
593 }
594 ($obj, $other) = ($other, $obj) if $inv;
595 bless [$meth, $obj, $other];
596 }
597 sub str {
598 my ($meth, $a, $b) = @{+shift};
599 $a = 'u' unless defined $a;
600 if (defined $b) {
601 "[$meth $a $b]";
602 } else {
603 "[$meth $a]";
604 }
605 }
606 my %subr = ( 'n' => sub {$_[0]} );
607 foreach my $op (split " ", $overload::ops{with_assign}) {
608 $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}";
609 }
610 my @bins = qw(binary 3way_comparison num_comparison str_comparison);
611 foreach my $op (split " ", "@overload::ops{ @bins }") {
612 $subr{$op} = eval "sub {shift() $op shift()}";
613 }
614 foreach my $op (split " ", "@overload::ops{qw(unary func)}") {
615 $subr{$op} = eval "sub {$op shift()}";
616 }
617 $subr{'++'} = $subr{'+'};
618 $subr{'--'} = $subr{'-'};
619
620 sub num {
621 my ($meth, $a, $b) = @{+shift};
622 my $subr = $subr{$meth}
623 or die "Do not know how to ($meth) in symbolic";
624 $a = $a->num if ref $a eq __PACKAGE__;
625 $b = $b->num if ref $b eq __PACKAGE__;
626 $subr->($a,$b);
627 }
628 sub TIESCALAR { my $pack = shift; $pack->new(@_) }
629 sub FETCH { shift }
630 sub vars { my $p = shift; tie($_, $p) foreach @_; }
631 sub STORE {
632 my $obj = shift;
633 $#$obj = 1;
634 $obj->[1] = shift;
635 }
636}
637
638{
639 my $foo = new symbolic1 11;
640 my $baz = $foo++;
641 is((sprintf "%d", $foo), '12');
642 is((sprintf "%d", $baz), '11');
643 my $bar = $foo;
644 $baz = ++$foo;
645 is((sprintf "%d", $foo), '13');
646 is((sprintf "%d", $bar), '12');
647 is((sprintf "%d", $baz), '13');
648 my $ban = $foo;
649 $baz = ($foo += 1);
650 is((sprintf "%d", $foo), '14');
651 is((sprintf "%d", $bar), '12');
652 is((sprintf "%d", $baz), '14');
653 is((sprintf "%d", $ban), '13');
654 $baz = 0;
655 $baz = $foo++;
656 is((sprintf "%d", $foo), '15');
657 is((sprintf "%d", $baz), '14');
658 is("$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]');
659}
660
661{
662 my $iter = new symbolic1 2;
663 my $side = new symbolic1 1;
664 my $cnt = $iter;
665
666 while ($cnt) {
667 $cnt = $cnt - 1; # The "simple" way
668 $side = (sqrt(1 + $side**2) - 1)/$side;
669 }
670 my $pi = $side*(2**($iter+2));
671 is("$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]');
672 is((sprintf "%f", $pi), '3.182598');
673}
674
675{
676 my $iter = new symbolic1 2;
677 my $side = new symbolic1 1;
678 my $cnt = $iter;
679
680 while ($cnt--) {
681 $side = (sqrt(1 + $side**2) - 1)/$side;
682 }
683 my $pi = $side*(2**($iter+2));
684 is("$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]');
685 is((sprintf "%f", $pi), '3.182598');
686}
687
688{
689 my ($a, $b);
690 symbolic1->vars($a, $b);
691 my $c = sqrt($a**2 + $b**2);
692 $a = 3; $b = 4;
693 is((sprintf "%d", $c), '5');
694 $a = 12; $b = 5;
695 is((sprintf "%d", $c), '13');
696}
697
698{
699 package two_face; # Scalars with separate string and
700 # numeric values.
701 sub new { my $p = shift; bless [@_], $p }
702 use overload '""' => \&str, '0+' => \&num, fallback => 1;
703 sub num {shift->[1]}
704 sub str {shift->[0]}
705}
706
707{
708 my $seven = new two_face ("vii", 7);
709 is((sprintf "seven=$seven, seven=%d, eight=%d", $seven, $seven+1),
710 'seven=vii, seven=7, eight=8');
711 is(scalar ($seven =~ /i/), '1');
712}
713
714{
715 package sorting;
716 use overload 'cmp' => \&comp;
717 sub new { my ($p, $v) = @_; bless \$v, $p }
718 sub comp { my ($x,$y) = @_; ($$x * 3 % 10) <=> ($$y * 3 % 10) or $$x cmp $$y }
719}
720{
721 my @arr = map sorting->new($_), 0..12;
722 my @sorted1 = sort @arr;
723 my @sorted2 = map $$_, @sorted1;
724 is("@sorted2", '0 10 7 4 1 11 8 5 12 2 9 6 3');
725}
726{
727 package iterator;
728 use overload '<>' => \&iter;
729 sub new { my ($p, $v) = @_; bless \$v, $p }
730 sub iter { my ($x) = @_; return undef if $$x < 0; return $$x--; }
731}
732
733{
734 my $iter = iterator->new(5);
735 my $acc = '';
736 my $out;
737 $acc .= " $out" while $out = <${iter}>;
738 is($acc, ' 5 4 3 2 1 0');
739 $iter = iterator->new(5);
740 is(scalar <${iter}>, '5');
741 $acc = '';
742 $acc .= " $out" while $out = <$iter>;
743 is($acc, ' 4 3 2 1 0');
744}
745{
746 package deref;
747 use overload '%{}' => \&hderef, '&{}' => \&cderef,
748 '*{}' => \&gderef, '${}' => \&sderef, '@{}' => \&aderef;
749 sub new { my ($p, $v) = @_; bless \$v, $p }
750 sub deref {
751 my ($self, $key) = (shift, shift);
752 my $class = ref $self;
753 bless $self, 'deref::dummy'; # Disable overloading of %{}
754 my $out = $self->{$key};
755 bless $self, $class; # Restore overloading
756 $out;
757 }
758 sub hderef {shift->deref('h')}
759 sub aderef {shift->deref('a')}
760 sub cderef {shift->deref('c')}
761 sub gderef {shift->deref('g')}
762 sub sderef {shift->deref('s')}
763}
764{
765 my $deref = bless { h => { foo => 5 , fake => 23 },
766 c => sub {return shift() + 34},
767 's' => \123,
768 a => [11..13],
769 g => \*srt,
770 }, 'deref';
771 # Hash:
772 my @cont = sort %$deref;
773 if ("\t" eq "\011") { # ASCII
774 is("@cont", '23 5 fake foo');
775 }
776 else { # EBCDIC alpha-numeric sort order
777 is("@cont", 'fake foo 23 5');
778 }
779 my @keys = sort keys %$deref;
780 is("@keys", 'fake foo');
781 my @val = sort values %$deref;
782 is("@val", '23 5');
783 is($deref->{foo}, 5);
784 is(defined $deref->{bar}, '');
785 my $key;
786 @keys = ();
787 push @keys, $key while $key = each %$deref;
788 @keys = sort @keys;
789 is("@keys", 'fake foo');
790 is(exists $deref->{bar}, '');
791 is(exists $deref->{foo}, 1);
792 # Code:
793 is($deref->(5), 39);
794 is(&$deref(6), 40);
795 sub xxx_goto { goto &$deref }
796 is(xxx_goto(7), 41);
797 my $srt = bless { c => sub {$b <=> $a}
798 }, 'deref';
799 *srt = \&$srt;
800 my @sorted = sort srt 11, 2, 5, 1, 22;
801 is("@sorted", '22 11 5 2 1');
802 # Scalar
803 is($$deref, 123);
804 # Code
805 @sorted = sort $srt 11, 2, 5, 1, 22;
806 is("@sorted", '22 11 5 2 1');
807 # Array
808 is("@$deref", '11 12 13');
809 is($#$deref, '2');
810 my $l = @$deref;
811 is($l, 3);
812 is($deref->[2], '13');
813 $l = pop @$deref;
814 is($l, 13);
815 $l = 1;
816 is($deref->[$l], '12');
817 # Repeated dereference
818 my $double = bless { h => $deref,
819 }, 'deref';
820 is($double->{foo}, 5);
821}
822
823{
824 package two_refs;
825 use overload '%{}' => \&gethash, '@{}' => sub { ${shift()} };
826 sub new {
827 my $p = shift;
828 bless \ [@_], $p;
829 }
830 sub gethash {
831 my %h;
832 my $self = shift;
833 tie %h, ref $self, $self;
834 \%h;
835 }
836
837 sub TIEHASH { my $p = shift; bless \ shift, $p }
838 my %fields;
839 my $i = 0;
840 $fields{$_} = $i++ foreach qw{zero one two three};
841 sub STORE {
842 my $self = ${shift()};
843 my $key = $fields{shift()};
844 defined $key or die "Out of band access";
845 $$self->[$key] = shift;
846 }
847 sub FETCH {
848 my $self = ${shift()};
849 my $key = $fields{shift()};
850 defined $key or die "Out of band access";
851 $$self->[$key];
852 }
853}
854
855my $bar = new two_refs 3,4,5,6;
856$bar->[2] = 11;
857is($bar->{two}, 11);
858$bar->{three} = 13;
859is($bar->[3], 13);
860
861{
862 package two_refs_o;
863 @ISA = ('two_refs');
864}
865
866$bar = new two_refs_o 3,4,5,6;
867$bar->[2] = 11;
868is($bar->{two}, 11);
869$bar->{three} = 13;
870is($bar->[3], 13);
871
872{
873 package two_refs1;
874 use overload '%{}' => sub { ${shift()}->[1] },
875 '@{}' => sub { ${shift()}->[0] };
876 sub new {
877 my $p = shift;
878 my $a = [@_];
879 my %h;
880 tie %h, $p, $a;
881 bless \ [$a, \%h], $p;
882 }
883 sub gethash {
884 my %h;
885 my $self = shift;
886 tie %h, ref $self, $self;
887 \%h;
888 }
889
890 sub TIEHASH { my $p = shift; bless \ shift, $p }
891 my %fields;
892 my $i = 0;
893 $fields{$_} = $i++ foreach qw{zero one two three};
894 sub STORE {
895 my $a = ${shift()};
896 my $key = $fields{shift()};
897 defined $key or die "Out of band access";
898 $a->[$key] = shift;
899 }
900 sub FETCH {
901 my $a = ${shift()};
902 my $key = $fields{shift()};
903 defined $key or die "Out of band access";
904 $a->[$key];
905 }
906}
907
908$bar = new two_refs_o 3,4,5,6;
909$bar->[2] = 11;
910is($bar->{two}, 11);
911$bar->{three} = 13;
912is($bar->[3], 13);
913
914{
915 package two_refs1_o;
916 @ISA = ('two_refs1');
917}
918
919$bar = new two_refs1_o 3,4,5,6;
920$bar->[2] = 11;
921is($bar->{two}, 11);
922$bar->{three} = 13;
923is($bar->[3], 13);
924
925{
926 package B;
927 use overload bool => sub { ${+shift} };
928}
929
930my $aaa;
931{ my $bbbb = 0; $aaa = bless \$bbbb, B }
932
933is !$aaa, 1;
934
935unless ($aaa) {
936 pass();
937} else {
938 fail();
939}
940
941# check that overload isn't done twice by join
942{ my $c = 0;
943 package Join;
944 use overload '""' => sub { $c++ };
945 my $x = join '', bless([]), 'pq', bless([]);
946 main::is $x, '0pq1';
947};
948
949# Test module-specific warning
950{
951 # check the Odd number of arguments for overload::constant warning
952 my $a = "" ;
953 local $SIG{__WARN__} = sub {$a = $_[0]} ;
954 $x = eval ' overload::constant "integer" ; ' ;
955 is($a, "");
956 use warnings 'overload' ;
957 $x = eval ' overload::constant "integer" ; ' ;
958 like($a, qr/^Odd number of arguments for overload::constant at/);
959}
960
961{
962 # check the '$_[0]' is not an overloadable type warning
963 my $a = "" ;
964 local $SIG{__WARN__} = sub {$a = $_[0]} ;
965 $x = eval ' overload::constant "fred" => sub {} ; ' ;
966 is($a, "");
967 use warnings 'overload' ;
968 $x = eval ' overload::constant "fred" => sub {} ; ' ;
969 like($a, qr/^'fred' is not an overloadable type at/);
970}
971
972{
973 # check the '$_[1]' is not a code reference warning
974 my $a = "" ;
975 local $SIG{__WARN__} = sub {$a = $_[0]} ;
976 $x = eval ' overload::constant "integer" => 1; ' ;
977 is($a, "");
978 use warnings 'overload' ;
979 $x = eval ' overload::constant "integer" => 1; ' ;
980 like($a, qr/^'1' is not a code reference at/);
981}
982
983{
984 # check the invalid argument warning [perl #74098]
985 my $a = "" ;
986 local $SIG{__WARN__} = sub {$a = $_[0]} ;
987 $x = eval ' use overload "~|_|~" => sub{} ' ;
988 eval ' no overload "~|_|~" ' ;
989 is($a, "");
990 use warnings 'overload' ;
991 $x = eval ' use overload "~|_|~" => sub{} ' ;
992 like($a, qr/^overload arg '~\|_\|~' is invalid at \(eval \d+\) line /,
993 'invalid arg warning');
994 undef $a;
995 eval ' no overload "~|_|~" ' ;
996 like($a, qr/^overload arg '~\|_\|~' is invalid at \(eval \d+\) line /,
997 'invalid arg warning');
998}
999
1000{
1001 my $c = 0;
1002 package ov_int1;
1003 use overload '""' => sub { 3+shift->[0] },
1004 '0+' => sub { 10+shift->[0] },
1005 'int' => sub { 100+shift->[0] };
1006 sub new {my $p = shift; bless [shift], $p}
1007
1008 package ov_int2;
1009 use overload '""' => sub { 5+shift->[0] },
1010 '0+' => sub { 30+shift->[0] },
1011 'int' => sub { 'ov_int1'->new(1000+shift->[0]) };
1012 sub new {my $p = shift; bless [shift], $p}
1013
1014 package noov_int;
1015 use overload '""' => sub { 2+shift->[0] },
1016 '0+' => sub { 9+shift->[0] };
1017 sub new {my $p = shift; bless [shift], $p}
1018
1019 package main;
1020
1021 my $x = new noov_int 11;
1022 my $int_x = int $x;
1023 main::is("$int_x", 20);
1024 $x = new ov_int1 31;
1025 $int_x = int $x;
1026 main::is("$int_x", 131);
1027 $x = new ov_int2 51;
1028 $int_x = int $x;
1029 main::is("$int_x", 1054);
1030}
1031
1032# make sure that we don't infinitely recurse
1033{
1034 my $c = 0;
1035 package Recurse;
1036 use overload '""' => sub { shift },
1037 '0+' => sub { shift },
1038 'bool' => sub { shift },
1039 fallback => 1;
1040 my $x = bless([]);
1041 # For some reason beyond me these have to be oks rather than likes.
1042 main::ok("$x" =~ /Recurse=ARRAY/);
1043 main::ok($x);
1044 main::ok($x+0 =~ qr/Recurse=ARRAY/);
1045}
1046
1047# BugID 20010422.003 (#6872)
1048package Foo;
1049
1050use overload
1051 'bool' => sub { return !$_[0]->is_zero() || undef; }
1052;
1053
1054sub is_zero
1055 {
1056 my $self = shift;
1057 return $self->{var} == 0;
1058 }
1059
1060sub new
1061 {
1062 my $class = shift;
1063 my $self = {};
1064 $self->{var} = shift;
1065 bless $self,$class;
1066 }
1067
1068package main;
1069
1070use strict;
1071
1072my $r = Foo->new(8);
1073$r = Foo->new(0);
1074
1075is(($r || 0), 0);
1076
1077package utf8_o;
1078
1079use overload
1080 '""' => sub { return $_[0]->{var}; }
1081 ;
1082
1083sub new
1084 {
1085 my $class = shift;
1086 my $self = {};
1087 $self->{var} = shift;
1088 bless $self,$class;
1089 }
1090
1091package main;
1092
1093
1094my $utfvar = new utf8_o 200.2.1;
1095is("$utfvar", 200.2.1); # 223 - stringify
1096is("a$utfvar", "a".200.2.1); # 224 - overload via sv_2pv_flags
1097
1098# 225..227 -- more %{} tests. Hangs in 5.6.0, okay in later releases.
1099# Basically this example implements strong encapsulation: if Hderef::import()
1100# were to eval the overload code in the caller's namespace, the privatisation
1101# would be quite transparent.
1102package Hderef;
1103use overload '%{}' => sub { caller(0) eq 'Foo' ? $_[0] : die "zap" };
1104package Foo;
1105@Foo::ISA = 'Hderef';
1106sub new { bless {}, shift }
1107sub xet { @_ == 2 ? $_[0]->{$_[1]} :
1108 @_ == 3 ? ($_[0]->{$_[1]} = $_[2]) : undef }
1109package main;
1110my $a = Foo->new;
1111$a->xet('b', 42);
1112is ($a->xet('b'), 42);
1113ok (!defined eval { $a->{b} });
1114like ($@, qr/zap/);
1115
1116{
1117 package t229;
1118 use overload '=' => sub { 42 },
1119 '++' => sub { my $x = ${$_[0]}; $_[0] };
1120 sub new { my $x = 42; bless \$x }
1121
1122 my $warn;
1123 {
1124 local $SIG{__WARN__} = sub { $warn++ };
1125 my $x = t229->new;
1126 my $y = $x;
1127 eval { $y++ };
1128 }
1129 main::ok (!$warn);
1130}
1131
1132{
1133 my ($int, $out1, $out2);
1134 {
1135 BEGIN { $int = 0; overload::constant 'integer' => sub {$int++; 17}; }
1136 $out1 = 0;
1137 $out2 = 1;
1138 }
1139 is($int, 2, "#24313"); # 230
1140 is($out1, 17, "#24313"); # 231
1141 is($out2, 17, "#24313"); # 232
1142}
1143
1144{
1145 package perl31793;
1146 use overload cmp => sub { 0 };
1147 package perl31793_fb;
1148 use overload cmp => sub { 0 }, fallback => 1;
1149 package main;
1150 my $o = bless [], 'perl31793';
1151 my $of = bless [], 'perl31793_fb';
1152 my $no = bless [], 'no_overload';
1153 like(overload::StrVal(\"scalar"), qr/^SCALAR\(0x[0-9a-f]+\)$/);
1154 like(overload::StrVal([]), qr/^ARRAY\(0x[0-9a-f]+\)$/);
1155 like(overload::StrVal({}), qr/^HASH\(0x[0-9a-f]+\)$/);
1156 like(overload::StrVal(sub{1}), qr/^CODE\(0x[0-9a-f]+\)$/);
1157 like(overload::StrVal(\*GLOB), qr/^GLOB\(0x[0-9a-f]+\)$/);
1158 like(overload::StrVal(\$o), qr/^REF\(0x[0-9a-f]+\)$/);
1159 like(overload::StrVal(qr/a/), qr/^Regexp=REGEXP\(0x[0-9a-f]+\)$/);
1160 like(overload::StrVal($o), qr/^perl31793=ARRAY\(0x[0-9a-f]+\)$/);
1161 like(overload::StrVal($of), qr/^perl31793_fb=ARRAY\(0x[0-9a-f]+\)$/);
1162 like(overload::StrVal($no), qr/^no_overload=ARRAY\(0x[0-9a-f]+\)$/);
1163}
1164
1165{
1166 package Numify;
1167 use overload (qw(0+ numify fallback 1));
1168
1169 sub new {
1170 my $val = $_[1];
1171 bless \$val, $_[0];
1172 }
1173
1174 sub numify { ${$_[0]} }
1175}
1176
1177# These all check that overloaded values, rather than reference addresses,
1178# are what are getting tested.
1179my ($two, $one, $un, $deux) = map {new Numify $_} 2, 1, 1, 2;
1180my ($ein, $zwei) = (1, 2);
1181
1182my %map = (one => 1, un => 1, ein => 1, deux => 2, two => 2, zwei => 2);
1183foreach my $op (qw(<=> == != < <= > >=)) {
1184 foreach my $l (keys %map) {
1185 foreach my $r (keys %map) {
1186 my $ocode = "\$$l $op \$$r";
1187 my $rcode = "$map{$l} $op $map{$r}";
1188
1189 my $got = eval $ocode;
1190 die if $@;
1191 my $expect = eval $rcode;
1192 die if $@;
1193 is ($got, $expect, $ocode) or print "# $rcode\n";
1194 }
1195 }
1196}
1197{
1198 # check that overloading works in regexes
1199 {
1200 package Foo493;
1201 use overload
1202 '""' => sub { "^$_[0][0]\$" },
1203 '.' => sub {
1204 bless [
1205 $_[2]
1206 ? (ref $_[1] ? $_[1][0] : $_[1]) . ':' .$_[0][0]
1207 : $_[0][0] . ':' . (ref $_[1] ? $_[1][0] : $_[1])
1208 ], 'Foo493'
1209 };
1210 }
1211
1212 my $a = bless [ "a" ], 'Foo493';
1213 like('a', qr/$a/);
1214 like('x:a', qr/x$a/);
1215 like('x:a:=', qr/x$a=$/);
1216 like('x:a:a:=', qr/x$a$a=$/);
1217
1218}
1219
1220{
1221 {
1222 package QRonly;
1223 use overload qr => sub { qr/x/ }, fallback => 1;
1224 }
1225 {
1226 my $x = bless [], "QRonly";
1227
1228 # like tries to be too clever, and decides that $x-stringified
1229 # doesn't look like a regex
1230 ok("x" =~ $x, "qr-only matches");
1231 ok("y" !~ $x, "qr-only doesn't match what it shouldn't");
1232 ok("x" =~ /^(??{$x})$/, "qr-only with ?? matches");
1233 ok("y" !~ /^(??{$x})$/, "qr-only with ?? doesn't match what it shouldn't");
1234 ok("xx" =~ /x$x/, "qr-only matches with concat");
1235 like("$x", qr/^QRonly=ARRAY/, "qr-only doesn't have string overload");
1236
1237 my $qr = bless qr/y/, "QRonly";
1238 ok("x" =~ $qr, "qr with qr-overload uses overload");
1239 ok("y" !~ $qr, "qr with qr-overload uses overload");
1240 ok("x" =~ /^(??{$qr})$/, "qr with qr-overload with ?? uses overload");
1241 ok("y" !~ /^(??{$qr})$/, "qr with qr-overload with ?? uses overload");
1242 is("$qr", "".qr/y/, "qr with qr-overload stringify");
1243
1244 my $rx = $$qr;
1245 ok("y" =~ $rx, "bare rx with qr-overload doesn't overload match");
1246 ok("x" !~ $rx, "bare rx with qr-overload doesn't overload match");
1247 ok("y" =~ /^(??{$rx})$/, "bare rx with qr-overload with ?? doesn't overload match");
1248 ok("x" !~ /^(??{$rx})$/, "bare rx with qr-overload with ?? doesn't overload match");
1249 is("$rx", "".qr/y/, "bare rx with qr-overload stringify");
1250 }
1251 {
1252 package QRandSTR;
1253 use overload qr => sub { qr/x/ }, q/""/ => sub { "y" };
1254 }
1255 {
1256 my $x = bless [], "QRandSTR";
1257 ok("x" =~ $x, "qr+str uses qr for match");
1258 ok("y" !~ $x, "qr+str uses qr for match");
1259 ok("xx" =~ /x$x/, "qr+str uses qr for match with concat");
1260 is("$x", "y", "qr+str uses str for stringify");
1261
1262 my $qr = bless qr/z/, "QRandSTR";
1263 is("$qr", "y", "qr with qr+str uses str for stringify");
1264 ok("xx" =~ /x$x/, "qr with qr+str uses qr for match");
1265
1266 my $rx = $$qr;
1267 ok("z" =~ $rx, "bare rx with qr+str doesn't overload match");
1268 is("$rx", "".qr/z/, "bare rx with qr+str doesn't overload stringify");
1269 }
1270 {
1271 package QRany;
1272 use overload qr => sub { $_[0]->(@_) };
1273
1274 package QRself;
1275 use overload qr => sub { $_[0] };
1276 }
1277 {
1278 my $rx = bless sub { ${ qr/x/ } }, "QRany";
1279 ok("x" =~ $rx, "qr overload accepts a bare rx");
1280 ok("y" !~ $rx, "qr overload accepts a bare rx");
1281
1282 my $str = bless sub { "x" }, "QRany";
1283 ok(!eval { "x" =~ $str }, "qr overload doesn't accept a string");
1284 like($@, qr/^Overloaded qr did not return a REGEXP/, "correct error");
1285
1286 my $oqr = bless qr/z/, "QRandSTR";
1287 my $oqro = bless sub { $oqr }, "QRany";
1288 ok("z" =~ $oqro, "qr overload doesn't recurse");
1289
1290 my $qrs = bless qr/z/, "QRself";
1291 ok("z" =~ $qrs, "qr overload can return self");
1292 }
1293 {
1294 package STRonly;
1295 use overload q/""/ => sub { "x" };
1296
1297 package STRonlyFB;
1298 use overload q/""/ => sub { "x" }, fallback => 1;
1299 }
1300 {
1301 my $fb = bless [], "STRonlyFB";
1302 ok("x" =~ $fb, "qr falls back to \"\"");
1303 ok("y" !~ $fb, "qr falls back to \"\"");
1304
1305 my $nofb = bless [], "STRonly";
1306 ok("x" =~ $nofb, "qr falls back even without fallback");
1307 ok("y" !~ $nofb, "qr falls back even without fallback");
1308 }
1309}
1310
1311{
1312 my $twenty_three = 23;
1313 # Check that constant overloading propagates into evals
1314 BEGIN { overload::constant integer => sub { 23 } }
1315 is(eval "17", $twenty_three);
1316}
1317
1318{
1319 # Check readonliness of constants, whether shared hash key
1320 # scalars or no (brought up in bug #109744)
1321 BEGIN { overload::constant integer => sub { "main" }; }
1322 eval { ${\5} = 'whatever' };
1323 like $@, qr/^Modification of a read-only value attempted at /,
1324 'constant overloading makes read-only constants';
1325 BEGIN { overload::constant integer => sub { __PACKAGE__ }; }
1326 eval { ${\5} = 'whatever' };
1327 like $@, qr/^Modification of a read-only value attempted at /,
1328 '... even with shared hash key scalars';
1329}
1330
1331{
1332 package Sklorsh;
1333 use overload
1334 bool => sub { shift->is_cool };
1335
1336 sub is_cool {
1337 $_[0]->{name} eq 'cool';
1338 }
1339
1340 sub delete {
1341 undef %{$_[0]};
1342 bless $_[0], 'Brap';
1343 return 1;
1344 }
1345
1346 sub delete_with_self {
1347 my $self = shift;
1348 undef %$self;
1349 bless $self, 'Brap';
1350 return 1;
1351 }
1352
1353 package Brap;
1354
1355 1;
1356
1357 package main;
1358
1359 my $obj;
1360 $obj = bless {name => 'cool'}, 'Sklorsh';
1361 $obj->delete;
1362 ok(eval {if ($obj) {1}; 1}, $@ || 'reblessed into nonexistent namespace');
1363
1364 $obj = bless {name => 'cool'}, 'Sklorsh';
1365 $obj->delete_with_self;
1366 ok (eval {if ($obj) {1}; 1}, $@);
1367
1368 my $a = $b = {name => 'hot'};
1369 bless $b, 'Sklorsh';
1370 is(ref $a, 'Sklorsh');
1371 is(ref $b, 'Sklorsh');
1372 ok(!$b, "Expect overloaded boolean");
1373 ok(!$a, "Expect overloaded boolean");
1374}
1375
1376{
1377 package Flrbbbbb;
1378 use overload
1379 bool => sub { shift->{truth} eq 'yes' },
1380 '0+' => sub { shift->{truth} eq 'yes' ? '1' : '0' },
1381 '!' => sub { shift->{truth} eq 'no' },
1382 fallback => 1;
1383
1384 sub new { my $class = shift; bless { truth => shift }, $class }
1385
1386 package main;
1387
1388 my $yes = Flrbbbbb->new('yes');
1389 my $x;
1390 $x = 1 if $yes; is($x, 1);
1391 $x = 2 unless $yes; is($x, 1);
1392 $x = 3 if !$yes; is($x, 1);
1393 $x = 4 unless !$yes; is($x, 4);
1394
1395 my $no = Flrbbbbb->new('no');
1396 $x = 0;
1397 $x = 1 if $no; is($x, 0);
1398 $x = 2 unless $no; is($x, 2);
1399 $x = 3 if !$no; is($x, 3);
1400 $x = 4 unless !$no; is($x, 3);
1401
1402 $x = 0;
1403 $x = 1 if !$no && $yes; is($x, 1);
1404 $x = 2 unless !$no && $yes; is($x, 1);
1405 $x = 3 if $no || !$yes; is($x, 1);
1406 $x = 4 unless $no || !$yes; is($x, 4);
1407
1408 $x = 0;
1409 $x = 1 if !$no || !$yes; is($x, 1);
1410 $x = 2 unless !$no || !$yes; is($x, 1);
1411 $x = 3 if !$no && !$yes; is($x, 1);
1412 $x = 4 unless !$no && !$yes; is($x, 4);
1413}
1414
1415{
1416 no warnings 'experimental::builtin';
1417 use builtin 'weaken';
1418
1419 package Shklitza;
1420 use overload '""' => sub {"CLiK KLAK"};
1421
1422 package Ksshfwoom;
1423
1424 package main;
1425
1426 my ($obj, $ref);
1427 $obj = bless do {my $a; \$a}, 'Shklitza';
1428 $ref = $obj;
1429
1430 is ("$obj", "CLiK KLAK");
1431 is ("$ref", "CLiK KLAK");
1432
1433 weaken $ref;
1434 is ("$ref", "CLiK KLAK");
1435
1436 bless $obj, 'Ksshfwoom';
1437
1438 like ($obj, qr/^Ksshfwoom=/);
1439 like ($ref, qr/^Ksshfwoom=/);
1440
1441 undef $obj;
1442 is ($ref, undef);
1443}
1444
1445{
1446 package bit;
1447 # bit operations have overloadable assignment variants too
1448
1449 sub new { bless \$_[1], $_[0] }
1450
1451 use overload
1452 "&=" => sub { bit->new($_[0]->val . ' & ' . $_[1]->val) },
1453 "^=" => sub { bit->new($_[0]->val . ' ^ ' . $_[1]->val) },
1454 "|" => sub { bit->new($_[0]->val . ' | ' . $_[1]->val) }, # |= by fallback
1455 ;
1456
1457 sub val { ${$_[0]} }
1458
1459 package main;
1460
1461 my $a = bit->new(my $va = 'a');
1462 my $b = bit->new(my $vb = 'b');
1463
1464 $a &= $b;
1465 is($a->val, 'a & b', "overloaded &= works");
1466
1467 my $c = bit->new(my $vc = 'c');
1468
1469 $b ^= $c;
1470 is($b->val, 'b ^ c', "overloaded ^= works");
1471
1472 my $d = bit->new(my $vd = 'd');
1473
1474 $c |= $d;
1475 is($c->val, 'c | d', "overloaded |= (by fallback) works");
1476}
1477
1478{
1479 # comparison operators with nomethod (bug 41546)
1480 my $warning = "";
1481 my $method;
1482
1483 package nomethod_false;
1484 use overload nomethod => sub { $method = 'nomethod'; 0 };
1485
1486 package nomethod_true;
1487 use overload nomethod => sub { $method= 'nomethod'; 'true' };
1488
1489 package main;
1490 local $^W = 1;
1491 local $SIG{__WARN__} = sub { $warning = $_[0] };
1492
1493 my $f = bless [], 'nomethod_false';
1494 ($warning, $method) = ("", "");
1495 is($f eq 'whatever', 0, 'nomethod makes eq return 0');
1496 is($method, 'nomethod');
1497
1498 my $t = bless [], 'nomethod_true';
1499 ($warning, $method) = ("", "");
1500 is($t eq 'whatever', 'true', 'nomethod makes eq return "true"');
1501 is($method, 'nomethod');
1502 is($warning, "", 'nomethod eq need not return number');
1503
1504 eval q{
1505 package nomethod_false;
1506 use overload cmp => sub { $method = 'cmp'; 0 };
1507 };
1508 $f = bless [], 'nomethod_false';
1509 ($warning, $method) = ("", "");
1510 ok($f eq 'whatever', 'eq falls back to cmp (nomethod not called)');
1511 is($method, 'cmp');
1512
1513 eval q{
1514 package nomethod_true;
1515 use overload cmp => sub { $method = 'cmp'; 'true' };
1516 };
1517 $t = bless [], 'nomethod_true';
1518 ($warning, $method) = ("", "");
1519 ok($t eq 'whatever', 'eq falls back to cmp (nomethod not called)');
1520 is($method, 'cmp');
1521 like($warning, qr/isn't numeric/, 'cmp should return number');
1522
1523}
1524
1525{
1526 # nomethod called for '!' after attempted fallback
1527 my $nomethod_called = 0;
1528
1529 package nomethod_not;
1530 use overload nomethod => sub { $nomethod_called = 'yes'; };
1531
1532 package main;
1533 my $o = bless [], 'nomethod_not';
1534 my $res = ! $o;
1535
1536 is($nomethod_called, 'yes', "nomethod() is called for '!'");
1537 is($res, 'yes', "nomethod(..., '!') return value propagates");
1538}
1539
1540{
1541 # Subtle bug pre 5.10, as a side effect of the overloading flag being
1542 # stored on the reference rather than the referent. Despite the fact that
1543 # objects can only be accessed via references (even internally), the
1544 # referent actually knows that it's blessed, not the references. So taking
1545 # a new, unrelated, reference to it gives an object. However, the
1546 # overloading-or-not flag was on the reference prior to 5.10, and taking
1547 # a new reference didn't (use to) copy it.
1548
1549 package kayo;
1550
1551 use overload '""' => sub {${$_[0]}};
1552
1553 sub Pie {
1554 return "$_[0], $_[1]";
1555 }
1556
1557 package main;
1558
1559 my $class = 'kayo';
1560 my $string = 'bam';
1561 my $crunch_eth = bless \$string, $class;
1562
1563 is("$crunch_eth", $string);
1564 is ($crunch_eth->Pie("Meat"), "$string, Meat");
1565
1566 my $wham_eth = \$string;
1567
1568 is("$wham_eth", $string,
1569 'This reference did not have overloading in 5.8.8 and earlier');
1570 is ($crunch_eth->Pie("Apple"), "$string, Apple");
1571
1572 my $class = ref $wham_eth;
1573 $class =~ s/=.*//;
1574
1575 # Bless it back into its own class!
1576 bless $wham_eth, $class;
1577
1578 is("$wham_eth", $string);
1579 is ($crunch_eth->Pie("Blackbird"), "$string, Blackbird");
1580}
1581
1582{
1583 package numify_int;
1584 use overload "0+" => sub { $_[0][0] += 1; 42 };
1585 package numify_self;
1586 use overload "0+" => sub { $_[0][0]++; $_[0] };
1587 package numify_other;
1588 use overload "0+" => sub { $_[0][0]++; $_[0][1] = bless [], 'numify_int' };
1589 package numify_by_fallback;
1590 use overload fallback => 1;
1591
1592 package main;
1593 my $o = bless [], 'numify_int';
1594 is(int($o), 42, 'numifies to integer');
1595 is($o->[0], 1, 'int() numifies only once');
1596
1597 my $aref = [];
1598 my $num_val = int($aref);
1599 my $r = bless $aref, 'numify_self';
1600 is(int($r), $num_val, 'numifies to self');
1601 is($r->[0], 1, 'int() numifies once when returning self');
1602
1603 my $s = bless [], 'numify_other';
1604 is(int($s), 42, 'numifies to numification of other object');
1605 is($s->[0], 1, 'int() numifies once when returning other object');
1606 is($s->[1][0], 1, 'returned object numifies too');
1607
1608 my $m = bless $aref, 'numify_by_fallback';
1609 is(int($m), $num_val, 'numifies to usual reference value');
1610 is(abs($m), $num_val, 'numifies to usual reference value');
1611 is(-$m, -$num_val, 'numifies to usual reference value');
1612 is(0+$m, $num_val, 'numifies to usual reference value');
1613 is($m+0, $num_val, 'numifies to usual reference value');
1614 is($m+$m, 2*$num_val, 'numifies to usual reference value');
1615 is(0-$m, -$num_val, 'numifies to usual reference value');
1616 is(1*$m, $num_val, 'numifies to usual reference value');
1617 is(int($m/1), $num_val, 'numifies to usual reference value');
1618 is($m%100, $num_val%100, 'numifies to usual reference value');
1619 is($m**1, $num_val, 'numifies to usual reference value');
1620
1621 is(abs($aref), $num_val, 'abs() of ref');
1622 is(-$aref, -$num_val, 'negative of ref');
1623 is(0+$aref, $num_val, 'ref addition');
1624 is($aref+0, $num_val, 'ref addition');
1625 is($aref+$aref, 2*$num_val, 'ref addition');
1626 is(0-$aref, -$num_val, 'subtraction of ref');
1627 is(1*$aref, $num_val, 'multiplicaton of ref');
1628 is(int($aref/1), $num_val, 'division of ref');
1629 is($aref%100, $num_val%100, 'modulo of ref');
1630 is($aref**1, $num_val, 'exponentiation of ref');
1631}
1632
1633{
1634 package CopyConstructorFallback;
1635 use overload
1636 '++' => sub { "$_[0]"; $_[0] },
1637 fallback => 1;
1638 sub new { bless {} => shift }
1639
1640 package main;
1641
1642 my $o = CopyConstructorFallback->new;
1643 my $x = $o++; # would segfault
1644 my $y = ++$o;
1645 is($x, $o, "copy constructor falls back to assignment (postinc)");
1646 is($y, $o, "copy constructor falls back to assignment (preinc)");
1647}
1648
1649# only scalar 'x' should currently overload
1650
1651{
1652 package REPEAT;
1653
1654 my ($x,$n, $nm);
1655
1656 use overload
1657 'x' => sub { $x++; 1 },
1658 '0+' => sub { $n++; 1 },
1659 'nomethod' => sub { $nm++; 1 },
1660 'fallback' => 0,
1661 ;
1662
1663 my $s = bless {};
1664
1665 package main;
1666
1667 my @a;
1668 my $count = 3;
1669
1670 ($x,$n,$nm) = (0,0,0);
1671 @a = ((1,2,$s) x $count);
1672 is("$x-$n-$nm", "0-0-0", 'repeat 1');
1673
1674 ($x,$n,$nm) = (0,0,0);
1675 @a = ((1,$s,3) x $count);
1676 is("$x-$n-$nm", "0-0-0", 'repeat 2');
1677
1678 ($x,$n,$nm) = (0,0,0);
1679 @a = ((1,2,3) x $s);
1680 is("$x-$n-$nm", "0-1-0", 'repeat 3');
1681}
1682
1683
1684
1685# RT #57012: magic items need to have mg_get() called before testing for
1686# overload. Lack of this means that overloaded values returned by eg a
1687# tied array didn't call overload methods.
1688# We test here both a tied array and scalar, since the implementation of
1689# tied arrays (and hashes) is such that in rvalue context, mg_get is
1690# called prior to executing the op, while it isn't for a tied scalar.
1691# We also check that return values are correctly tainted.
1692# We try against two overload packages; one has all expected methods, the
1693# other uses only fallback methods.
1694
1695{
1696
1697 # @tests holds a list of test cases. Each elem is an array ref with
1698 # the following entries:
1699 #
1700 # * the value that the overload method should return
1701 #
1702 # * the expression to be evaled. %s is replaced with the
1703 # variable being tested ($ta[0], $ts, or $plain)
1704 #
1705 # * a string listing what functions we expect to be called.
1706 # Each method appends its name in parentheses, so "(=)(+)" means
1707 # we expect the copy constructor and then the add method to be
1708 # called.
1709 #
1710 # * like above, but what should be called for the fallback-only test
1711 # (in this case, nomethod() identifies itself as "(NM:*)" where *
1712 # is the op). If this value is undef, fallback tests are skipped.
1713 #
1714 # * An array ref of expected counts of calls to FETCH/STORE.
1715 # The first three values are:
1716 # 1. the expected number of FETCHs for a tied array
1717 # 2. the expected number of FETCHs for a tied scalar
1718 # 3. the expected number of STOREs
1719 # If there are a further three elements present, then
1720 # these represent the expected counts for the fallback
1721 # version of the tests. If absent, they are assumed to
1722 # be the same as for the full method test
1723 #
1724 # * Under the taint version of the tests, whether we expect
1725 # the result to be tainted (for example comparison ops
1726 # like '==' don't return a tainted value, even if their
1727 # args are.
1728 my @tests;
1729
1730 my %subs;
1731 my $funcs;
1732 my $use_int;
1733
1734 BEGIN {
1735 # A note on what methods to expect to be called, and
1736 # how many times FETCH/STORE is called:
1737 #
1738 # Mutating ops (+=, ++ etc) trigger a copy ('='), since
1739 # the code can't distinguish between something that's been copied:
1740 # $a = foo->new(0); $b = $a; refcnt($$b) == 2
1741 # and overloaded objects stored in ties which will have extra
1742 # refcounts due to the tied_obj magic and entries on the tmps
1743 # stack when returning from FETCH etc. So we always copy.
1744
1745 # This accounts for a '=', and an extra STORE.
1746 # We also have a FETCH returning the final value from the eval,
1747 # plus a FETCH in the overload subs themselves: ($_[0][0])
1748 # triggers one. However, tied aggregates have a mechanism to prevent
1749 # multiple fetches between STOREs, which means that the tied
1750 # hash skips doing a FETCH during '='.
1751
1752 for (qw(+ - * / % ** << >> & | ^)) {
1753 my $op = $_;
1754 $op = '%%' if $op eq '%';
1755 my $e = "%s $op= 3";
1756 $subs{"$_="} = $e;
1757 # ARRAY FETCH: initial, sub+=, eval-return,
1758 # SCALAR FETCH: initial, sub=, sub+=, eval-return,
1759 # STORE: copy, mutator
1760 push @tests, [ 18, $e, "(=)($_=)", "(=)(NM:$_=)", [ 3, 4, 2 ], 1 ];
1761
1762 $subs{$_} =
1763 "do { my \$arg = %s; \$_[2] ? (3 $op \$arg) : (\$arg $op 3) }";
1764 # ARRAY FETCH: initial
1765 # SCALAR FETCH: initial eval-return,
1766 push @tests, [ 18, "%s $op 3", "($_)", "(NM:$_)", [ 1, 2, 0 ], 1 ];
1767 push @tests, [ 18, "3 $op %s", "($_)", "(NM:$_)", [ 1, 2, 0 ], 1 ];
1768 }
1769
1770 # these use string fallback rather than nomethod
1771 for (qw(x .)) {
1772 my $op = $_;
1773 my $e = "%s $op= 3";
1774 $subs{"$_="} = $e;
1775 # For normal case:
1776 # ARRAY FETCH: initial, sub+=, eval-return,
1777 # SCALAR FETCH: initial, sub=, sub+=, eval-return,
1778 # STORE: copy, mutator
1779 # for fallback, we just stringify, so eval-return and copy skipped
1780
1781 push @tests, [ 18, $e, "(=)($_=)", '("")',
1782 [ 3, 4, 2, 2, 3, 1 ], 1 ];
1783
1784 $subs{$_} =
1785 "do { my \$arg = %s; \$_[2] ? (3 $op \$arg) : (\$arg $op 3) }";
1786 # ARRAY FETCH: initial
1787 # SCALAR FETCH: initial eval-return,
1788 # with fallback, we just stringify, so eval-return skipped,
1789 # but an extra FETCH happens in sub"", except for 'x',
1790 # which passes a copy of the RV to sub"", avoiding the
1791 # second FETCH
1792
1793 push @tests, [ 18, "%s $op 3", "($_)", '("")',
1794 [ 1, 2, 0, 1, ($_ eq '.' ? 2 : 1), 0 ], 1 ];
1795 next if $_ eq 'x'; # repeat only overloads on LHS
1796 push @tests, [ 18, "3 $op %s", "($_)", '("")',
1797 [ 1, 2, 0, 1, 2, 0 ], 1 ];
1798 }
1799
1800 for (qw(++ --)) {
1801 my $pre = "$_%s";
1802 my $post = "%s$_";
1803 $subs{$_} = $pre;
1804 push @tests,
1805 # ARRAY FETCH: initial, sub+=, eval-return,
1806 # SCALAR FETCH: initial, sub=, sub+=, eval-return,
1807 # STORE: copy, mutator
1808 [ 18, $pre, "(=)($_)(\"\")", "(=)(NM:$_)(\"\")", [ 3, 4, 2 ], 1 ],
1809 # ARRAY FETCH: initial, sub+=
1810 # SCALAR FETCH: initial, sub=, sub+=
1811 # STORE: copy, mutator
1812 [ 18, $post, "(=)($_)(\"\")", "(=)(NM:$_)(\"\")", [ 2, 3, 2 ], 1 ];
1813 }
1814
1815 # For the non-mutator ops, we have a initial FETCH,
1816 # an extra FETCH within the sub itself for the scalar option,
1817 # and no STOREs
1818
1819 for (qw(< <= > >= == != lt le gt ge eq ne)) {
1820 my $e = "%s $_ 3";
1821 $subs{$_} = $e;
1822 push @tests, [ 3, $e, "($_)", "(NM:$_)", [ 1, 2, 0 ], 0 ];
1823 }
1824 for (qw(<=> cmp)) {
1825 my $e = "%s $_ 3";
1826 $subs{$_} = $e;
1827 push @tests, [ 3, $e, "($_)", "(NM:$_)", [ 1, 2, 0 ], 1 ];
1828 }
1829 for (qw(atan2)) {
1830 my $e = "$_ %s, 3";
1831 $subs{$_} = $e;
1832 push @tests, [ 18, $e, "($_)", "(NM:$_)", [ 1, 2, 0 ], 1 ];
1833 }
1834 for (qw(cos sin exp abs log sqrt int ~)) {
1835 my $e = "$_(%s)";
1836 $subs{$_} = $e;
1837 push @tests, [ 1.23, $e, "($_)",
1838 ($_ eq 'int' ? '(0+)' : "(NM:$_)") , [ 1, 2, 0 ], 1 ];
1839 }
1840 for (qw(!)) {
1841 my $e = "$_(%s)";
1842 $subs{$_} = $e;
1843 push @tests, [ 1.23, $e, "($_)", '(0+)', [ 1, 2, 0 ], 0 ];
1844 }
1845 for (qw(-)) {
1846 my $e = "$_(%s)";
1847 $subs{neg} = $e;
1848 push @tests, [ 18, $e, '(neg)', '(NM:neg)', [ 1, 2, 0 ], 1 ];
1849 }
1850 my $e = '(%s) ? 1 : 0';
1851 $subs{bool} = $e;
1852 push @tests, [ 18, $e, '(bool)', '(0+)', [ 1, 2, 0 ], 0 ];
1853
1854 # note: this is testing unary qr, not binary =~
1855 $subs{qr} = '(qr/%s/)';
1856 push @tests, [ "abc", '"abc" =~ (%s)', '(qr)', '("")', [ 1, 2, 0 ], 0 ];
1857 push @tests, [ chr 256, 'chr(256) =~ (%s)', '(qr)', '("")',
1858 [ 1, 2, 0 ], 0 ];
1859
1860 $e = '"abc" ~~ (%s)';
1861 $subs{'~~'} = $e;
1862 push @tests, [ "abc", $e, '(~~)', '(NM:~~)', [ 1, 1, 0 ], 0 ];
1863
1864 $subs{'-X'} = 'do { my $f = (%s);'
1865 . '$_[1] eq "r" ? (-r ($f)) :'
1866 . '$_[1] eq "e" ? (-e ($f)) :'
1867 . '$_[1] eq "f" ? (-f ($f)) :'
1868 . '$_[1] eq "l" ? (-l ($f)) :'
1869 . '$_[1] eq "t" ? (-t ($f)) :'
1870 . '$_[1] eq "T" ? (-T ($f)) : 0;}';
1871 # Note - we don't care what these file tests return, as
1872 # long as the tied and untied versions return the same value.
1873 # The flags below are chosen to test all uses of tryAMAGICftest_MG
1874 for (qw(r e f l t T)) {
1875 push @tests, [ 'TEST', "-$_ (%s)", '(-X)', '("")', [ 1, 2, 0 ], 0 ];
1876 }
1877
1878 $subs{'${}'} = '%s';
1879 push @tests, [ do {my $s=99; \$s}, '${%s}', '(${})', undef, [ 1, 1, 0 ], 0 ];
1880
1881 # we skip testing '@{}' here because too much of this test
1882 # framework involves array dereferences!
1883
1884 $subs{'%{}'} = '%s';
1885 push @tests, [ {qw(a 1 b 2 c 3)}, 'join "", sort keys %%{%s}',
1886 '(%{})', undef, [ 1, 1, 0 ], 0 ];
1887
1888 $subs{'&{}'} = '%s';
1889 push @tests, [ sub {99}, 'do {&{%s} for 1,2}',
1890 '(&{})(&{})', undef, [ 2, 2, 0 ], 0 ];
1891
1892 our $RT57012A = 88;
1893 our $RT57012B;
1894 $subs{'*{}'} = '%s';
1895 push @tests, [ \*RT57012A, '*RT57012B = *{%s}; our $RT57012B',
1896 '(*{})', undef, [ 1, 1, 0 ], 0 ];
1897
1898 my $iter_text = ("some random text\n" x 100) . $^X;
1899 open my $iter_fh, '<', \$iter_text
1900 or die "open of \$iter_text gave ($!)\n";
1901 $subs{'<>'} = '<$iter_fh>';
1902 push @tests, [ $iter_fh, '<%s>', '(<>)', undef, [ 1, 1, 0 ], 1 ];
1903 push @tests, [ $iter_fh,
1904 'local *CORE::GLOBAL::glob = sub {}; eval q|<%s>|',
1905 '(<>)', undef, [ 1, 1, 0 ], 1 ];
1906
1907 # eval should do tie, overload on its arg before checking taint */
1908 push @tests, [ '1;', 'eval q(eval %s); $@ =~ /Insecure/',
1909 '("")', '("")', [ 1, 1, 0 ], 0 ];
1910
1911
1912 for my $sub (keys %subs) {
1913 no warnings 'deprecated';
1914 my $term = $subs{$sub};
1915 my $t = sprintf $term, '$_[0][0]';
1916 my $e ="sub { \$funcs .= '($sub)'; my \$r; if (\$use_int) {"
1917 . "use integer; \$r = ($t) } else { \$r = ($t) } \$r }";
1918 $subs{$sub} = eval $e;
1919 die "Compiling sub gave error:\n<$e>\n<$@>\n" if $@;
1920 }
1921 }
1922
1923 my $fetches;
1924 my $stores;
1925
1926 package RT57012_OV;
1927
1928 use overload
1929 %subs,
1930 "=" => sub { $funcs .= '(=)'; bless [ $_[0][0] ] },
1931 '0+' => sub { $funcs .= '(0+)'; 0 + $_[0][0] },
1932 '""' => sub { $funcs .= '("")'; "$_[0][0]" },
1933 ;
1934
1935 package RT57012_OV_FB; # only contains fallback conversion functions
1936
1937 use overload
1938 "=" => sub { $funcs .= '(=)'; bless [ $_[0][0] ] },
1939 '0+' => sub { $funcs .= '(0+)'; 0 + $_[0][0] },
1940 '""' => sub { $funcs .= '("")'; "$_[0][0]" },
1941 "nomethod" => sub {
1942 $funcs .= "(NM:$_[3])";
1943 my $e = defined($_[1])
1944 ? $_[3] eq 'atan2'
1945 ? $_[2]
1946 ? "atan2(\$_[1],\$_[0][0])"
1947 : "atan2(\$_[0][0],\$_[1])"
1948 : $_[2]
1949 ? "\$_[1] $_[3] \$_[0][0]"
1950 : "\$_[0][0] $_[3] \$_[1]"
1951 : $_[3] eq 'neg'
1952 ? "-\$_[0][0]"
1953 : "$_[3](\$_[0][0])";
1954 my $r;
1955 no warnings 'deprecated';
1956 if ($use_int) {
1957 use integer; $r = eval $e;
1958 }
1959 else {
1960 $r = eval $e;
1961 }
1962 ::diag("eval of nomethod <$e> gave <$@>") if $@;
1963 $r;
1964 }
1965
1966 ;
1967
1968 package RT57012_TIE_S;
1969
1970 my $tie_val;
1971 sub TIESCALAR { bless [ bless [ $tie_val ], $_[1] ] }
1972 sub FETCH { $fetches++; $_[0][0] }
1973 sub STORE { $stores++; $_[0][0] = $_[1] }
1974
1975 package RT57012_TIE_A;
1976
1977 sub TIEARRAY { bless [] }
1978 sub FETCH { $fetches++; $_[0][0] }
1979 sub STORE { $stores++; $_[0][$_[1]] = $_[2] }
1980
1981 package main;
1982
1983 for my $test (@tests) {
1984 my ($val, $sub_term, $exp_funcs, $exp_fb_funcs,
1985 $exp_counts, $exp_taint) = @$test;
1986
1987 my $tainted_val;
1988 {
1989 # create tainted version of $val (unless its a ref)
1990 my $t = substr($^X,0,0);
1991 my $t0 = $t."0";
1992 my $val1 = $val; # use a copy to avoid stringifying original
1993 $tainted_val = ref($val1) ? $val :
1994 ($val1 =~ /^[\d\.]+$/) ? $val+$t0 : $val.$t;
1995 }
1996 $tie_val = $tainted_val;
1997
1998 for my $int ('', 'use integer; ') {
1999 $use_int = ($int ne '');
2000 my $plain = $tainted_val;
2001 my $plain_term = $int . sprintf $sub_term, '$plain';
2002 my $exp = do {no warnings 'deprecated'; eval $plain_term };
2003 diag("eval of plain_term <$plain_term> gave <$@>") if $@;
2004 SKIP: {
2005 is_if_taint_supported(tainted($exp), $exp_taint,
2006 "<$plain_term> taint of expected return");
2007 }
2008
2009 for my $ov_pkg (qw(RT57012_OV RT57012_OV_FB)) {
2010 next if $ov_pkg eq 'RT57012_OV_FB'
2011 and not defined $exp_fb_funcs;
2012 my ($exp_fetch_a, $exp_fetch_s, $exp_store) =
2013 ($ov_pkg eq 'RT57012_OV' || @$exp_counts < 4)
2014 ? @$exp_counts[0,1,2]
2015 : @$exp_counts[3,4,5];
2016
2017 tie my $ts, 'RT57012_TIE_S', $ov_pkg;
2018 tie my @ta, 'RT57012_TIE_A';
2019 $ta[0] = bless [ $tainted_val ], $ov_pkg;
2020 my $oload = bless [ $tainted_val ], $ov_pkg;
2021
2022 for my $var ('$ta[0]', '$ts', '$oload',
2023 ($sub_term eq '<%s>' ? '${ts}' : ())
2024 ) {
2025
2026 $funcs = '';
2027 $fetches = 0;
2028 $stores = 0;
2029
2030 my $res_term = $int . sprintf $sub_term, $var;
2031 my $desc = "<$res_term> $ov_pkg" ;
2032 my $res = do { no warnings 'deprecated'; eval $res_term };
2033 diag("eval of res_term $desc gave <$@>") if $@;
2034 # uniquely, the inc/dec ops return the original
2035 # ref rather than a copy, so stringify it to
2036 # find out if its tainted
2037 $res = "$res" if $res_term =~ /\+\+|--/;
2038 SKIP: {
2039 is_if_taint_supported(tainted($res), $exp_taint,
2040 "$desc taint of result return");
2041 }
2042 is($res, $exp, "$desc return value");
2043 my $fns =($ov_pkg eq 'RT57012_OV_FB')
2044 ? $exp_fb_funcs : $exp_funcs;
2045 if ($var eq '$oload' && $res_term !~ /oload(\+\+|--)/) {
2046 # non-tied overloading doesn't trigger a copy
2047 # except for post inc/dec
2048 $fns =~ s/^\(=\)//;
2049 }
2050 is($funcs, $fns, "$desc methods called");
2051 next if $var eq '$oload';
2052 my $exp_fetch = ($var eq '$ts') ?
2053 $exp_fetch_s : $exp_fetch_a;
2054 SKIP: {
2055 if ($skip_fetch_count_when_no_taint{$desc} && $no_taint_support) {
2056 skip("your perl was built without taint support");
2057 }
2058 else {
2059 is($fetches, $exp_fetch, "$desc FETCH count");
2060 }
2061 }
2062 is($stores, $exp_store, "$desc STORE count");
2063
2064 }
2065
2066 }
2067 }
2068 }
2069}
2070
2071# Test overload from the main package
2072fresh_perl_is
2073 '$^W = 1; use overload q\""\ => sub {"ning"}; print bless []',
2074 'ning',
2075 { switches => ['-wl'], stderr => 1 },
2076 'use overload from the main package'
2077;
2078
2079{
2080 package blessed_methods;
2081 use overload '+' => sub {};
2082 bless overload::Method __PACKAGE__,'+';
2083 eval { overload::Method __PACKAGE__,'+' };
2084 ::is($@, '', 'overload::Method and blessed overload methods');
2085}
2086
2087{
2088 # fallback to 'cmp' and '<=>' with heterogeneous operands
2089 # [perl #71286]
2090 my $not_found = 'no method found';
2091 my $used = 0;
2092 package CmpBase;
2093 sub new {
2094 my $n = $_[1] || 0;
2095 bless \$n, ref $_[0] || $_[0];
2096 }
2097 sub cmp {
2098 $used = \$_[0];
2099 (${$_[0]} <=> ${$_[1]}) * ($_[2] ? -1 : 1);
2100 }
2101
2102 package NCmp;
2103 use parent '-norequire', 'CmpBase';
2104 use overload '<=>' => 'cmp';
2105
2106 package SCmp;
2107 use parent '-norequire', 'CmpBase';
2108 use overload 'cmp' => 'cmp';
2109
2110 package main;
2111 my $n = NCmp->new(5);
2112 my $s = SCmp->new(3);
2113 my $res;
2114
2115 eval { $res = $n > $s; };
2116 $res = $not_found if $@ =~ /$not_found/;
2117 is($res, 1, 'A>B using A<=> when B overloaded, no B<=>');
2118
2119 eval { $res = $s < $n; };
2120 $res = $not_found if $@ =~ /$not_found/;
2121 is($res, 1, 'A<B using B<=> when A overloaded, no A<=>');
2122
2123 eval { $res = $s lt $n; };
2124 $res = $not_found if $@ =~ /$not_found/;
2125 is($res, 1, 'A lt B using A:cmp when B overloaded, no B:cmp');
2126
2127 eval { $res = $n gt $s; };
2128 $res = $not_found if $@ =~ /$not_found/;
2129 is($res, 1, 'A gt B using B:cmp when A overloaded, no A:cmp');
2130
2131 my $o = NCmp->new(9);
2132 $res = $n < $o;
2133 is($used, \$n, 'A < B uses <=> from A in preference to B');
2134
2135 my $t = SCmp->new(7);
2136 $res = $s lt $t;
2137 is($used, \$s, 'A lt B uses cmp from A in preference to B');
2138}
2139
2140{
2141 # Combinatorial testing of 'fallback' and 'nomethod'
2142 # [perl #71286]
2143 package NuMB;
2144 use overload '0+' => sub { ${$_[0]}; },
2145 '""' => 'str';
2146 sub new {
2147 my $self = shift;
2148 my $n = @_ ? shift : 0;
2149 bless my $obj = \$n, ref $self || $self;
2150 }
2151 sub str {
2152 no strict qw/refs/;
2153 my $s = "(${$_[0]} ";
2154 $s .= "nomethod, " if defined ${ref($_[0]).'::(nomethod'};
2155 my $fb = ${ref($_[0]).'::()'};
2156 $s .= "fb=" . (defined $fb ? 0 + $fb : 'undef') . ")";
2157 }
2158 sub nomethod { "${$_[0]}.nomethod"; }
2159
2160 # create classes for tests
2161 package main;
2162 my @falls = (0, 'undef', 1);
2163 my @nomethods = ('', 'nomethod');
2164 my $not_found = 'no method found';
2165 for my $fall (@falls) {
2166 for my $nomethod (@nomethods) {
2167 my $nomethod_decl = $nomethod
2168 ? $nomethod . "=>'nomethod'," : '';
2169 eval qq{
2170 package NuMB$fall$nomethod;
2171 use parent '-norequire', qw/NuMB/;
2172 use overload $nomethod_decl
2173 fallback => $fall;
2174 };
2175 }
2176 }
2177
2178 # operation and precedence of 'fallback' and 'nomethod'
2179 # for all combinations with 2 overloaded operands
2180 for my $nomethod2 (@nomethods) {
2181 for my $nomethod1 (@nomethods) {
2182 for my $fall2 (@falls) {
2183 my $pack2 = "NuMB$fall2$nomethod2";
2184 for my $fall1 (@falls) {
2185 my $pack1 = "NuMB$fall1$nomethod1";
2186 my ($test, $out, $exp);
2187 eval qq{
2188 my \$x = $pack1->new(2);
2189 my \$y = $pack2->new(3);
2190 \$test = "\$x" . ' * ' . "\$y";
2191 \$out = \$x * \$y;
2192 };
2193 $out = $not_found if $@ =~ /$not_found/;
2194 $exp = $nomethod1 ? '2.nomethod' :
2195 $nomethod2 ? '3.nomethod' :
2196 $fall1 eq '1' && $fall2 eq '1' ? 6
2197 : $not_found;
2198 is($out, $exp, "$test --> $exp");
2199 }
2200 }
2201 }
2202 }
2203
2204 # operation of 'fallback' and 'nomethod'
2205 # where the other operand is not overloaded
2206 for my $nomethod (@nomethods) {
2207 for my $fall (@falls) {
2208 my ($test, $out, $exp);
2209 eval qq{
2210 my \$x = NuMB$fall$nomethod->new(2);
2211 \$test = "\$x" . ' * 3';
2212 \$out = \$x * 3;
2213 };
2214 $out = $not_found if $@ =~ /$not_found/;
2215 $exp = $nomethod ? '2.nomethod' :
2216 $fall eq '1' ? 6
2217 : $not_found;
2218 is($out, $exp, "$test --> $exp");
2219
2220 eval qq{
2221 my \$x = NuMB$fall$nomethod->new(2);
2222 \$test = '3 * ' . "\$x";
2223 \$out = 3 * \$x;
2224 };
2225 $out = $not_found if $@ =~ /$not_found/;
2226 is($out, $exp, "$test --> $exp");
2227 }
2228 }
2229}
2230
2231# since 5.6 overloaded <> was leaving an extra arg on the stack!
2232
2233{
2234 package Iter1;
2235 use overload '<>' => sub { 11 };
2236 package main;
2237 my $a = bless [], 'Iter1';
2238 my $x;
2239 my @a = (10, ($x = <$a>), 12);
2240 is ($a[0], 10, 'Iter1: a[0]');
2241 is ($a[1], 11, 'Iter1: a[1]');
2242 is ($a[2], 12, 'Iter1: a[2]');
2243 @a = (10, ($x .= <$a>), 12);
2244 is ($a[0], 10, 'Iter1: a[0] concat');
2245 is ($a[1], 1111, 'Iter1: a[1] concat');
2246 is ($a[2], 12, 'Iter1: a[2] concat');
2247}
2248
2249# Some tests for error messages
2250{
2251 package Justus;
2252 use overload '+' => 'justice';
2253 eval {"".bless[]};
2254 ::like $@, qr/^Can't resolve method "justice" overloading "\+" in p(?x:
2255 )ackage "Justus" at /,
2256 'Error message when explicitly named overload method does not exist';
2257
2258 package JustUs;
2259 our @ISA = 'JustYou';
2260 package JustYou { use overload '+' => 'injustice'; }
2261 "JustUs"->${\"(+"};
2262 eval {"".bless []};
2263 ::like $@, qr/^Stub found while resolving method "\?{3}" overloadin(?x:
2264 )g "\+" in package "JustUs" at /,
2265 'Error message when sub stub is encountered';
2266}
2267
2268{
2269 # check that the right number of stringifications
2270 # and the correct un-utf8-ifying happen on regex compile
2271 package utf8_match;
2272 my $c;
2273 use overload '""' => sub { $c++; $_[0][0] ? "^\x{100}\$" : "^A\$"; };
2274 my $o = bless [0], 'utf8_match';
2275
2276 $o->[0] = 0;
2277 $c = 0;
2278 ::ok("A" =~ "^A\$", "regex stringify utf8=0 ol=0 bytes=0");
2279 ::ok("A" =~ $o, "regex stringify utf8=0 ol=1 bytes=0");
2280 ::is($c, 1, "regex stringify utf8=0 ol=1 bytes=0 count");
2281
2282 $o->[0] = 1;
2283 $c = 0;
2284 ::ok("\x{100}" =~ "^\x{100}\$",
2285 "regex stringify utf8=1 ol=0 bytes=0");
2286 ::ok("\x{100}" =~ $o, "regex stringify utf8=1 ol=1 bytes=0");
2287 ::is($c, 1, "regex stringify utf8=1 ol=1 bytes=0 count");
2288
2289 use bytes;
2290
2291 $o->[0] = 0;
2292 $c = 0;
2293 ::ok("A" =~ "^A\$", "regex stringify utf8=0 ol=0 bytes=1");
2294 ::ok("A" =~ $o, "regex stringify utf8=0 ol=1 bytes=1");
2295 ::is($c, 1, "regex stringify utf8=0 ol=1 bytes=1 count");
2296
2297 $o->[0] = 1;
2298 $c = 0;
2299 ::ok(main::byte_utf8a_to_utf8n("\xc4\x80") =~ "^\x{100}\$",
2300 "regex stringify utf8=1 ol=0 bytes=1");
2301 ::ok(main::byte_utf8a_to_utf8n("\xc4\x80") =~ $o, "regex stringify utf8=1 ol=1 bytes=1");
2302 ::is($c, 1, "regex stringify utf8=1 ol=1 bytes=1 count");
2303
2304
2305}
2306
2307# [perl #40333]
2308# overload::Overloaded should not use a ->can designed for autoloading.
2309# This example attempts to be as realistic as possible. The o class has a
2310# default singleton object, but can have instances, too. The proxy class
2311# represents proxies for o objects, but class methods delegate to the
2312# singleton.
2313# overload::Overloaded used to return incorrect results for proxy objects.
2314package proxy {
2315 sub new { bless [$_[1]], $_[0] }
2316 sub AUTOLOAD {
2317 our $AUTOLOAD =~ s/.*:://;
2318 &_self->$AUTOLOAD;
2319 }
2320 sub can { SUPER::can{@_} || &_self->can($_[1]) }
2321 sub _self { ref $_[0] ? $_[0][0] : $o::singleton }
2322}
2323package o { use overload '""' => sub { 'keck' };
2324 sub new { bless[], $_[0] }
2325 our $singleton = o->new; }
2326ok !overload::Overloaded(new proxy new o),
2327 'overload::Overloaded does not incorrectly return true for proxy classes';
2328
2329# Another test, based on the type of explosive test class for which
2330# perl #40333 was filed.
2331{
2332 package broken_can;
2333 sub can {}
2334 use overload '""' => sub {"Ahoy!"};
2335
2336 package main;
2337 my $obj = bless [], 'broken_can';
2338 ok(overload::Overloaded($obj));
2339}
2340
2341sub eleventative::cos { 'eleven' }
2342sub twelvetative::abs { 'twelve' }
2343sub thirteentative::abs { 'thirteen' }
2344sub fourteentative::abs { 'fourteen' }
2345@eleventative::ISA = twelvetative::;
2346{
2347 my $o = bless [], 'eleventative';
2348 eval 'package eleventative; use overload map +($_)x2, cos=>abs=>';
2349 is cos $o, 'eleven', 'overloading applies to object blessed before';
2350 bless [], 'eleventative';
2351 is cos $o, 'eleven',
2352 'ovrld applies to previously-blessed obj after other obj is blessed';
2353 $o = bless [], 'eleventative';
2354 *eleventative::cos = sub { 'ten' };
2355 is cos $o, 'ten', 'method changes affect overloading';
2356 @eleventative::ISA = thirteentative::;
2357 is abs $o, 'thirteen', 'isa changes affect overloading';
2358 bless $o, 'fourteentative';
2359 @fourteentative::ISA = 'eleventative';
2360 is abs $o, 'fourteen', 'isa changes can turn overloading on';
2361}
2362
2363# no overload "fallback";
2364{ package phake;
2365 use overload fallback => 1, '""' => sub { 'arakas' };
2366 no overload 'fallback';
2367}
2368$a = bless [], 'phake';
2369is "$a", "arakas",
2370 'no overload "fallback" does not stop overload from working';
2371ok !eval { () = $a eq 'mpizeli'; 1 },
2372 'no overload "fallback" resets fallback to undef on overloaded class';
2373{ package ent; use overload fallback => 0, abs => sub{};
2374 our@ISA = 'huorn';
2375 package huorn;
2376 use overload fallback => 1;
2377 package ent;
2378 no overload "fallback"; # disable previous declaration
2379}
2380$a = bless [], ent::;
2381is eval {"$a"}, overload::StrVal($a),
2382 'no overload undoes fallback declaration completetly'
2383 or diag $@;
2384
2385# inherited fallback
2386{
2387 package pervyy;
2388 our @ISA = 'vtoryy';
2389 use overload "abs" =>=> sub {};
2390 package vtoryy;
2391 use overload fallback => 1, 'sin' =>=> sub{}
2392}
2393$a = bless [], pervyy::;
2394is eval {"$a"}, overload::StrVal($a),
2395 'fallback is inherited by classes that have their own overloading'
2396 or diag $@;
2397
2398# package separators in method names
2399{
2400 package mane;
2401 use overload q\""\ => "bear::strength";
2402 use overload bool => "bear'bouillon";
2403}
2404@bear::ISA = 'food';
2405sub food::strength { 'twine' }
2406sub food::bouillon { 0 }
2407$a = bless[], mane::;
2408is eval { "$a" }, 'twine', ':: in method name' or diag $@;
2409is eval { !$a }, 1, "' in method name" or diag $@;
2410
2411# [perl #113050] Half of CPAN assumes fallback is under "()"
2412{
2413 package dodo;
2414 use overload '+' => sub {};
2415 no strict;
2416 *{"dodo::()"} = sub{};
2417 ${"dodo::()"} = 1;
2418}
2419$a = bless [],'dodo';
2420is eval {"$a"}, overload::StrVal($a), 'fallback is stored under "()"';
2421
2422# [perl #47119]
2423{
2424 my $context;
2425
2426 {
2427 package Splitter;
2428 use overload '<>' => \&chars;
2429
2430 sub new {
2431 my $class = shift;
2432 my ($string) = @_;
2433 bless \$string, $class;
2434 }
2435
2436 sub chars {
2437 my $self = shift;
2438 my @chars = split //, $$self;
2439 $context = wantarray;
2440 return @chars;
2441 }
2442 }
2443
2444 my $obj = Splitter->new('bar');
2445
2446 $context = 42; # not 1, '', or undef
2447
2448 my @foo = <$obj>;
2449 is($context, 1, "list context (readline list)");
2450 is(scalar(@foo), 3, "correct result (readline list)");
2451 is($foo[0], 'b', "correct result (readline list)");
2452 is($foo[1], 'a', "correct result (readline list)");
2453 is($foo[2], 'r', "correct result (readline list)");
2454
2455 $context = 42;
2456
2457 my $foo = <$obj>;
2458 ok(defined($context), "scalar context (readline scalar)");
2459 is($context, '', "scalar context (readline scalar)");
2460 is($foo, 3, "correct result (readline scalar)");
2461
2462 $context = 42;
2463
2464 <$obj>;
2465 ok(!defined($context), "void context (readline void)");
2466
2467 $context = 42;
2468
2469 my @bar = <${obj}>;
2470 is($context, 1, "list context (glob list)");
2471 is(scalar(@bar), 3, "correct result (glob list)");
2472 is($bar[0], 'b', "correct result (glob list)");
2473 is($bar[1], 'a', "correct result (glob list)");
2474 is($bar[2], 'r', "correct result (glob list)");
2475
2476 $context = 42;
2477
2478 my $bar = <${obj}>;
2479 ok(defined($context), "scalar context (glob scalar)");
2480 is($context, '', "scalar context (glob scalar)");
2481 is($bar, 3, "correct result (glob scalar)");
2482
2483 $context = 42;
2484
2485 <${obj}>;
2486 ok(!defined($context), "void context (glob void)");
2487}
2488{
2489 my $context;
2490
2491 {
2492 package StringWithContext;
2493 use overload '""' => \&stringify;
2494
2495 sub new {
2496 my $class = shift;
2497 my ($string) = @_;
2498 bless \$string, $class;
2499 }
2500
2501 sub stringify {
2502 my $self = shift;
2503 $context = wantarray;
2504 return $$self;
2505 }
2506 }
2507
2508 my $obj = StringWithContext->new('bar');
2509
2510 $context = 42;
2511
2512 my @foo = "".$obj;
2513 ok(defined($context), "scalar context (stringify list)");
2514 is($context, '', "scalar context (stringify list)");
2515 is(scalar(@foo), 1, "correct result (stringify list)");
2516 is($foo[0], 'bar', "correct result (stringify list)");
2517
2518 $context = 42;
2519
2520 my $foo = "".$obj;
2521 ok(defined($context), "scalar context (stringify scalar)");
2522 is($context, '', "scalar context (stringify scalar)");
2523 is($foo, 'bar', "correct result (stringify scalar)");
2524
2525 $context = 42;
2526
2527 "".$obj;
2528
2529 is($context, '', "scalar context (stringify void)");
2530}
2531{
2532 my ($context, $swap);
2533
2534 {
2535 package AddWithContext;
2536 use overload '+' => \&add;
2537
2538 sub new {
2539 my $class = shift;
2540 my ($num) = @_;
2541 bless \$num, $class;
2542 }
2543
2544 sub add {
2545 my $self = shift;
2546 my ($other, $swapped) = @_;
2547 $context = wantarray;
2548 $swap = $swapped;
2549 return ref($self)->new($$self + $other);
2550 }
2551
2552 sub val { ${ $_[0] } }
2553 }
2554
2555 my $obj = AddWithContext->new(6);
2556
2557 $context = $swap = 42;
2558
2559 my @foo = $obj + 7;
2560 ok(defined($context), "scalar context (add list)");
2561 is($context, '', "scalar context (add list)");
2562 ok(defined($swap), "not swapped (add list)");
2563 is($swap, '', "not swapped (add list)");
2564 is(scalar(@foo), 1, "correct result (add list)");
2565 is($foo[0]->val, 13, "correct result (add list)");
2566
2567 $context = $swap = 42;
2568
2569 @foo = 7 + $obj;
2570 ok(defined($context), "scalar context (add list swap)");
2571 is($context, '', "scalar context (add list swap)");
2572 ok(defined($swap), "swapped (add list swap)");
2573 is($swap, 1, "swapped (add list swap)");
2574 is(scalar(@foo), 1, "correct result (add list swap)");
2575 is($foo[0]->val, 13, "correct result (add list swap)");
2576
2577 $context = $swap = 42;
2578
2579 my $foo = $obj + 7;
2580 ok(defined($context), "scalar context (add scalar)");
2581 is($context, '', "scalar context (add scalar)");
2582 ok(defined($swap), "not swapped (add scalar)");
2583 is($swap, '', "not swapped (add scalar)");
2584 is($foo->val, 13, "correct result (add scalar)");
2585
2586 $context = $swap = 42;
2587
2588 my $foo = 7 + $obj;
2589 ok(defined($context), "scalar context (add scalar swap)");
2590 is($context, '', "scalar context (add scalar swap)");
2591 ok(defined($swap), "swapped (add scalar swap)");
2592 is($swap, 1, "swapped (add scalar swap)");
2593 is($foo->val, 13, "correct result (add scalar swap)");
2594
2595 $context = $swap = 42;
2596
2597 $obj + 7;
2598
2599 ok(!defined($context), "void context (add void)");
2600 ok(defined($swap), "not swapped (add void)");
2601 is($swap, '', "not swapped (add void)");
2602
2603 $context = $swap = 42;
2604
2605 7 + $obj;
2606
2607 ok(!defined($context), "void context (add void swap)");
2608 ok(defined($swap), "swapped (add void swap)");
2609 is($swap, 1, "swapped (add void swap)");
2610
2611 $obj = AddWithContext->new(6);
2612
2613 $context = $swap = 42;
2614
2615 my @foo = $obj += 7;
2616 ok(defined($context), "scalar context (add assign list)");
2617 is($context, '', "scalar context (add assign list)");
2618 ok(!defined($swap), "not swapped and autogenerated (add assign list)");
2619 is(scalar(@foo), 1, "correct result (add assign list)");
2620 is($foo[0]->val, 13, "correct result (add assign list)");
2621 is($obj->val, 13, "correct result (add assign list)");
2622
2623 $obj = AddWithContext->new(6);
2624
2625 $context = $swap = 42;
2626
2627 my $foo = $obj += 7;
2628 ok(defined($context), "scalar context (add assign scalar)");
2629 is($context, '', "scalar context (add assign scalar)");
2630 ok(!defined($swap), "not swapped and autogenerated (add assign scalar)");
2631 is($foo->val, 13, "correct result (add assign scalar)");
2632 is($obj->val, 13, "correct result (add assign scalar)");
2633
2634 $obj = AddWithContext->new(6);
2635
2636 $context = $swap = 42;
2637
2638 $obj += 7;
2639
2640 ok(defined($context), "scalar context (add assign void)");
2641 is($context, '', "scalar context (add assign void)");
2642 ok(!defined($swap), "not swapped and autogenerated (add assign void)");
2643 is($obj->val, 13, "correct result (add assign void)");
2644
2645 $obj = AddWithContext->new(6);
2646
2647 $context = $swap = 42;
2648
2649 my @foo = ++$obj;
2650 ok(defined($context), "scalar context (add incr list)");
2651 is($context, '', "scalar context (add incr list)");
2652 ok(!defined($swap), "not swapped and autogenerated (add incr list)");
2653 is(scalar(@foo), 1, "correct result (add incr list)");
2654 is($foo[0]->val, 7, "correct result (add incr list)");
2655 is($obj->val, 7, "correct result (add incr list)");
2656
2657 $obj = AddWithContext->new(6);
2658
2659 $context = $swap = 42;
2660
2661 my $foo = ++$obj;
2662 ok(defined($context), "scalar context (add incr scalar)");
2663 is($context, '', "scalar context (add incr scalar)");
2664 ok(!defined($swap), "not swapped and autogenerated (add incr scalar)");
2665 is($foo->val, 7, "correct result (add incr scalar)");
2666 is($obj->val, 7, "correct result (add incr scalar)");
2667
2668 $obj = AddWithContext->new(6);
2669
2670 $context = $swap = 42;
2671
2672 ++$obj;
2673
2674 ok(defined($context), "scalar context (add incr void)");
2675 is($context, '', "scalar context (add incr void)");
2676 ok(!defined($swap), "not swapped and autogenerated (add incr void)");
2677 is($obj->val, 7, "correct result (add incr void)");
2678}
2679
2680# [perl #113010]
2681{
2682 {
2683 package OnlyFallback;
2684 use overload fallback => 0;
2685 }
2686 {
2687 my $obj = bless {}, 'OnlyFallback';
2688 my $died = !eval { "".$obj; 1 };
2689 my $err = $@;
2690 ok($died, "fallback of 0 causes error");
2691 like($err, qr/"\.": no method found/, "correct error");
2692 }
2693
2694 {
2695 package OnlyFallbackUndef;
2696 use overload fallback => undef;
2697 }
2698 {
2699 my $obj = bless {}, 'OnlyFallbackUndef';
2700 my $died = !eval { "".$obj; 1 };
2701 my $err = $@;
2702 ok($died, "fallback of undef causes error");
2703 # this one tries falling back to stringify before dying
2704 like($err, qr/"""": no method found/, "correct error");
2705 }
2706
2707 {
2708 package OnlyFallbackTrue;
2709 use overload fallback => 1;
2710 }
2711 {
2712 my $obj = bless {}, 'OnlyFallbackTrue';
2713 my $val;
2714 my $died = !eval { $val = "".$obj; 1 };
2715 my $err = $@;
2716 ok(!$died, "fallback of 1 doesn't cause error")
2717 || diag("got error of $err");
2718 like($val, qr/^OnlyFallbackTrue=HASH\(/, "stringified correctly");
2719 }
2720}
2721
2722{
2723 # Making Regexp class overloaded: avoid infinite recursion.
2724 # Do this in a separate process since it, well, overloads Regexp!
2725 fresh_perl_is(
2726 <<'EOF',
2727package Regexp;
2728use overload q{""} => sub {$_[0] };
2729package main;
2730my $r1 = qr/1/;
2731my $r2 = qr/ABC$r1/;
2732print $r2,"\n";
2733EOF
2734 '(?^:ABC(?^:1))',
2735 { stderr => 1 },
2736 'overloaded REGEXP'
2737 );
2738}
2739
2740{
2741 # RT #121362
2742 # splitting the stash HV while rebuilding the overload cache gave
2743 # valgrind errors. This test code triggers such a split. It doesn't
2744 # actually test anything; its just there for valgrind to spot
2745 # problems.
2746
2747 package A_121362;
2748
2749 sub stringify { }
2750 use overload '""' => 'stringify';
2751
2752 package B_121362;
2753 our @ISA = qw(A_121362);
2754
2755 package main;
2756
2757 my $x = bless { }, 'B_121362';
2758
2759 for ('a'..'z') {
2760 delete $B_121362::{stringify}; # delete cache entry
2761 no strict 'refs';
2762 *{"B_121362::$_"} = sub { }; # increase size of %B_121362
2763 my $y = $x->{value}; # trigger cache add to %B_121362
2764 }
2765 pass("RT 121362");
2766}
2767
2768package refsgalore {
2769 use overload
2770 '${}' => sub { \42 },
2771 '@{}' => sub { [43] },
2772 '%{}' => sub { { 44 => 45 } },
2773 '&{}' => sub { sub { 46 } };
2774}
2775{
2776 use feature 'postderef';
2777 tell myio; # vivifies *myio{IO} at compile time
2778 use constant ioref => bless *myio{IO}, refsgalore::;
2779 is ioref->$*, 42, '(overloaded constant that is not a scalar ref)->$*';
2780 is ioref->[0], 43, '(ovrld constant that is not an array ref)->[0]';
2781 is ioref->{44}, 45, "(ovrld const that is not a hash ref)->{key}";
2782 is ioref->(), 46, '(overloaded constant that is not a sub ref)->()';
2783}
2784
2785package xstack { use overload 'x' => sub { shift . " x " . shift },
2786 '""'=> sub { "xstack" } }
2787is join(",", 1..3, scalar((bless([], 'xstack')) x 3, 1), 4..6),
2788 "1,2,3,1,4,5,6",
2789 '(...)x... in void cx with x overloaded [perl #121827]';
2790
2791package bitops {
2792 our @o;
2793 use overload do {
2794 my %o;
2795 for my $o (qw(& | ^ ~ &. |. ^. ~. &= |= ^= &.= |.= ^.=)) {
2796 $o{$o} = sub {
2797 ::ok !defined $_[3], "undef (or nonexistent) arg 3 for $o";
2798 push @o, $o, scalar @_, $_[4]//'u';
2799 $_[0]
2800 }
2801 }
2802 %o, '=' => sub { bless [] };
2803 }
2804}
2805{
2806 use experimental 'bitwise';
2807 my $o = bless [], bitops::;
2808 $_ = $o & 0;
2809 $_ = $o | 0;
2810 $_ = $o ^ 0;
2811 $_ = ~$o;
2812 $_ = $o &. 0;
2813 $_ = $o |. 0;
2814 $_ = $o ^. 0;
2815 $_ = ~.$o;
2816 $o &= 0;
2817 $o |= 0;
2818 $o ^= 0;
2819 $o &.= 0;
2820 $o |.= 0;
2821 $o ^.= 0;
2822 # elems are in triplets: op, length of @_, numeric? (1/u for y/n)
2823 is "@bitops::o", '& 5 1 | 5 1 ^ 5 1 ~ 5 1 &. 3 u |. 3 u ^. 3 u ~. 3 u ' . '&= 5 1 |= 5 1 ^= 5 1 &.= 3 u |.= 3 u ^.= 3 u',
2824 'experimental "bitwise" ops'
2825}
2826package bitops2 {
2827 our @o;
2828 use overload
2829 nomethod => sub { push @o, $_[3], scalar @_, $_[4]//'u'; $_[0] },
2830 '=' => sub { bless [] };
2831}
2832{
2833 use experimental 'bitwise';
2834 my $o = bless [], bitops2::;
2835 $_ = $o & 0;
2836 $_ = $o | 0;
2837 $_ = $o ^ 0;
2838 $_ = ~$o;
2839 $_ = $o &. 0;
2840 $_ = $o |. 0;
2841 $_ = $o ^. 0;
2842 $_ = ~.$o;
2843 $o &= 0;
2844 $o |= 0;
2845 $o ^= 0;
2846 $o &.= 0;
2847 $o |.= 0;
2848 $o ^.= 0;
2849 # elems are in triplets: op, length of @_, numeric? (1/u for y/n)
2850 is "@bitops2::o", '& 5 1 | 5 1 ^ 5 1 ~ 5 1 &. 4 u |. 4 u ^. 4 u ~. 4 u ' . '&= 5 1 |= 5 1 ^= 5 1 &.= 4 u |.= 4 u ^.= 4 u',
2851 'experimental "bitwise" ops with nomethod'
2852}
2853
2854package length_utf8 {
2855 use overload '""' => sub { "\x{100}" };
2856 my $o = bless [];
2857print length $o, "\n";
2858
2859 ::is length($o), 1, "overloaded utf8 length";
2860 ::is "$o", "\x{100}", "overloaded utf8 value";
2861}
2862
2863
2864{ # undefining the overload stash -- KEEP THIS TEST LAST
2865 package ant;
2866 use overload '+' => 'onion';
2867 $_ = \&overload::nil;
2868 undef %overload::;
2869 ()=0+bless[];
2870 ::ok(1, 'no crash when undefining %overload::');
2871}
2872
2873
2874# test various aspects of string concat overloading, especially where
2875# multiple concats etc are optimised into a single multiconcat op
2876
2877package Concat {
2878
2879 my $id;
2880
2881 # append a brief description of @_ to $id
2882 sub id {
2883 my @a = map ref $_ ? "[" . $_->[0] . "]" :
2884 !defined $_ ? "u" :
2885 $_,
2886 @_;
2887 $id .= '(' . join (',', @a) . ')';
2888 }
2889
2890 use overload
2891 '.' => sub {
2892 id('.', @_);
2893 my ($l, $r, $rev) = @_;
2894 ($l, $r) = map ref $_ ? $_->[0] : $_, $l, $r;
2895 ($l,$r) = ($r, $l) if $rev;
2896 bless [ $l . $r ];
2897 },
2898
2899 '.=' => sub {
2900 id('.=', @_);
2901 my ($l, $r, $rev) = @_;
2902 my ($ll, $rr) = map ref $_ ? $_->[0] : $_, $l, $r;
2903 die "Unexpected reverse in .=" if $rev;
2904 $l->[0] .= ref $r ? $r->[0] : $r;
2905 $l;
2906 },
2907
2908 '=' => sub {
2909 id('=', @_);
2910 bless [ $_[0][0] ];
2911 },
2912
2913 '""' => sub {
2914 id('""', @_);
2915 $_[0][0];
2916 },
2917 ;
2918
2919 my $a = 'a';
2920 my $b = 'b';
2921 my $c = 'c';
2922 my $A = bless [ 'A' ];
2923 my $B = bless [ 'B' ];
2924 my $C = bless [ 'C' ];
2925
2926 my ($r, $R);
2927
2928
2929 # like cc, but with $is_ref set to 1
2930 sub c {
2931 my ($expr, $expect, $exp_id) = @_;
2932 cc($expr, $expect, 1, $exp_id);
2933 }
2934
2935 # eval $expr, and see if it returns $expect, and whether
2936 # the returned value is a ref ($is_ref). Finally, check that
2937 # $id, which has accumulated info from all overload method calls,
2938 # matches $exp_id.
2939
2940 sub cc {
2941 my ($expr, $expect, $is_ref, $exp_id) = @_;
2942
2943 $id = '';
2944 $r = 'r';
2945 $R = bless ['R'];
2946
2947 my $got = eval $expr;
2948 die "eval failed: $@" if $@;
2949 ::is "$got", $expect, "expect: $expr";
2950 ::is $id, $exp_id, "id: $expr";
2951 ::is ref($got), ($is_ref ? 'Concat' : ''), "is_ref: $expr";
2952 }
2953
2954 # single concats
2955
2956 c '$r=$A.$b', 'Ab', '(.,[A],b,)("",[Ab],u,)';
2957 c '$r=$a.$B', 'aB', '(.,[B],a,1)("",[aB],u,)';
2958 c '$r=$A.$B', 'AB', '(.,[A],[B],)("",[AB],u,)';
2959 c '$R.=$a', 'Ra', '(.=,[R],a,u)("",[Ra],u,)';
2960 c '$R.=$A', 'RA', '(.=,[R],[A],u)("",[RA],u,)';
2961
2962 # two concats
2963
2964 c '$r=$A.$b.$c', 'Abc', '(.,[A],b,)(.=,[Ab],c,u)("",[Abc],u,)';
2965 c '$r=$A.($b.$c)', 'Abc', '(.,[A],bc,)("",[Abc],u,)';
2966 c '$r=$a.$B.$c', 'aBc', '(.,[B],a,1)(.=,[aB],c,u)("",[aBc],u,)';
2967 c '$r=$a.($B.$c)', 'aBc', '(.,[B],c,)(.,[Bc],a,1)("",[aBc],u,)';
2968 c '$r=$a.$b.$C', 'abC', '(.,[C],ab,1)("",[abC],u,)';
2969 c '$r=$a.($b.$C)', 'abC', '(.,[C],b,1)(.,[bC],a,1)("",[abC],u,)';
2970
2971 # two concats plus mutator
2972
2973 c '$r.=$A.$b.$c', 'rAbc', '(.,[A],b,)(.=,[Ab],c,u)(.,[Abc],r,1)'
2974 .'("",[rAbc],u,)';
2975 c '$r.=$A.($b.$c)', 'rAbc', '(.,[A],bc,)(.,[Abc],r,1)("",[rAbc],u,)';
2976 c '$r.=$a.$B.$c', 'raBc', '(.,[B],a,1)(.=,[aB],c,u)(.,[aBc],r,1)'
2977 .'("",[raBc],u,)';
2978 c '$r.=$a.($B.$c)', 'raBc', '(.,[B],c,)(.,[Bc],a,1)(.,[aBc],r,1)'
2979 .'("",[raBc],u,)';
2980 c '$r.=$a.$b.$C', 'rabC', '(.,[C],ab,1)(.,[abC],r,1)("",[rabC],u,)';
2981 c '$r.=$a.($b.$C)', 'rabC', '(.,[C],b,1)(.,[bC],a,1)(.,[abC],r,1)'
2982 .'("",[rabC],u,)';
2983
2984 c '$R.=$A.$b.$c', 'RAbc', '(.,[A],b,)(.=,[Ab],c,u)(.=,[R],[Abc],u)'
2985 .'("",[RAbc],u,)';
2986 c '$R.=$A.($b.$c)', 'RAbc', '(.,[A],bc,)(.=,[R],[Abc],u)("",[RAbc],u,)';
2987 c '$R.=$a.$B.$c', 'RaBc', '(.,[B],a,1)(.=,[aB],c,u)(.=,[R],[aBc],u)'
2988 .'("",[RaBc],u,)';
2989 c '$R.=$a.($B.$c)', 'RaBc', '(.,[B],c,)(.,[Bc],a,1)(.=,[R],[aBc],u)'
2990 .'("",[RaBc],u,)';
2991 c '$R.=$a.$b.$C', 'RabC', '(.,[C],ab,1)(.=,[R],[abC],u)("",[RabC],u,)';
2992 c '$R.=$a.($b.$C)', 'RabC', '(.,[C],b,1)(.,[bC],a,1)(.=,[R],[abC],u)'
2993 .'("",[RabC],u,)';
2994
2995 # concat over assign
2996
2997 c '($R.=$a).$B.$c', 'RaBc', '(.=,[R],a,u)(.,[Ra],[B],)(.=,[RaB],c,u)'
2998 .'("",[RaBc],u,)';
2999 ::is "$R", "Ra", 'R in concat over assign';
3000
3001
3002 # nested mutators
3003
3004 c '(($R.=$a).=$b).=$c', 'Rabc', '(.=,[R],a,u)(=,[Ra],u,)(.=,[Ra],b,u)'
3005 . '(=,[Rab],u,)(.=,[Rab],c,u)("",[Rabc],u,)';
3006 c '(($R.=$a).=$B).=$c', 'RaBc', '(.=,[R],a,u)(=,[Ra],u,)(.=,[Ra],[B],u)'
3007 . '(=,[RaB],u,)(.=,[RaB],c,u)("",[RaBc],u,)';
3008
3009 # plain SV on both LHS and RHS with RHS object
3010
3011 c '$r=$r.$A.$r', 'rAr', '(.,[A],r,1)(.=,[rA],r,u)("",[rAr],u,)';
3012 c '$r.=$r.$A.$r', 'rrAr', '(.,[A],r,1)(.=,[rA],r,u)(.,[rAr],r,1)'
3013 .'("",[rrAr],u,)';
3014
3015 # object on both LHS and RHS
3016
3017 c '$R.=$R', 'RR', '(.=,[R],[R],u)("",[RR],u,)';
3018 c '$R.=$R.$b.$c', 'RRbc', '(.,[R],b,)(.=,[Rb],c,u)(.=,[R],[Rbc],u)'
3019 .'("",[RRbc],u,)';
3020 c '$R.=$a.$R.$c', 'RaRc', '(.,[R],a,1)(.=,[aR],c,u)(.=,[R],[aRc],u)'
3021 .'("",[RaRc],u,)';
3022 c '$R.=$a.$b.$R', 'RabR', '(.,[R],ab,1)(.=,[R],[abR],u)("",[RabR],u,)';
3023
3024
3025 # sprintf shouldn't do concat overloading
3026
3027 cc '$r=sprintf("%s%s%s",$a,$B,$c)', 'aBc', 0, '("",[B],u,)';
3028 cc '$R=sprintf("%s%s%s",$a,$B,$c)', 'aBc', 0, '("",[B],u,)';
3029 cc '$r.=sprintf("%s%s%s",$a,$B,$c)', 'raBc', 0, '("",[B],u,)';
3030 cc '$R.=sprintf("%s%s%s",$a,$B,$c)', 'RaBc', 1, '("",[B],u,)(.=,[R],aBc,u)'
3031 .'("",[RaBc],u,)';
3032
3033 # multiple constants should individually overload (RT #132385)
3034
3035 c '$r=$A."b"."c"', 'Abc', '(.,[A],b,)(.=,[Ab],c,u)("",[Abc],u,)';
3036
3037 # ... except for this
3038 c '$R.="a"."b"', 'Rab', '(.=,[R],ab,u)("",[Rab],u,)';
3039}
3040
3041# RT #132385
3042# The first arg of a reversed concat shouldn't be stringified:
3043# $left . $right
3044# where $right is overloaded, should invoke
3045# concat($right, $left, 1)
3046# rather than
3047# concat($right, "$left", 1)
3048# There's a similar issue with
3049# $left .= $right
3050# when left is overloaded
3051
3052package RT132385 {
3053
3054 use constant C => [ "constref" ];
3055
3056 use overload '.' => sub {
3057 my ($l, $r, $rev) = @_;
3058 ($l,$r) = ($r,$l) if $rev;
3059 $l = ref $l ? $l->[0] : "$l";
3060 $r = ref $r ? $r->[0] : "$r";
3061 "$l-$r";
3062 }
3063 ;
3064
3065 my $r1 = [ "ref1" ];
3066 my $r2 = [ "ref2" ];
3067 my $s1 = "str1";
3068
3069 my $o = bless [ "obj" ];
3070
3071 # try variations that will call either pp_concat or pp_multiconcat,
3072 # with the ref as the first or a later arg
3073
3074 ::is($r1.$o, "ref1-obj", "RT #132385 r1.o");
3075 ::is($r1.$o.$s1 , "ref1-objstr1", "RT #132385 r1.o.s1");
3076 ::is("const".$o.$s1 ,"const-objstr1", "RT #132385 const.o.s1");
3077 ::is(C.$o.$s1 ,"constref-objstr1", "RT #132385 C.o.s1");
3078
3079 ::like($r1.$r2.$o, qr/^ARRAY\(0x\w+\)ARRAY\(0x\w+\)-obj/,
3080 "RT #132385 r1.r2.o");
3081
3082 # ditto with a mutator
3083 ::is($o .= $r1, "obj-ref1", "RT #132385 o.=r1");
3084}
3085
3086# the RHS of an overloaded .= should be passed as-is to the overload
3087# method, rather than being stringified or otherwise being processed in
3088# such a way that it triggers an undef warning
3089package RT132783 {
3090 use warnings;
3091 use overload '.=' => sub { return "foo" };
3092 my $w = 0;
3093 local $SIG{__WARN__} = sub { $w++ };
3094 my $undef;
3095 my $ov = bless [];
3096 $ov .= $undef;
3097 ::is($w, 0, "RT #132783 - should be no warnings");
3098}
3099
3100# changing the overloaded object to a plain string within an overload
3101# method should be permanent.
3102package RT132827 {
3103 use overload '""' => sub { $_[0] = "a" };
3104 my $ov = bless [];
3105 my $b = $ov . "b";
3106 ::is(ref \$ov, "SCALAR", "RT #132827");
3107}
3108
3109# RT #132793
3110# An arg like "$b" in $overloaded .= "$b" should be stringified
3111# before being passed to the method
3112
3113package RT132793 {
3114 my $type;
3115 my $str = 0;
3116 use overload
3117 '.=' => sub { $type = ref(\$_[1]); "foo"; },
3118 '""' => sub { $str++; "bar" };
3119
3120 my $a = bless {};
3121 my $b = bless {};
3122 $a .= "$b";
3123 ::is($type, "SCALAR", "RT #132793 type");
3124 ::is($str, 1, "RT #132793 stringify count");
3125}
3126
3127# RT #132801
3128# A second RHS-not-stringified bug
3129
3130package RT132801 {
3131 my $type;
3132 my $str = 0;
3133 my $concat = 0;
3134 use overload
3135 '.' => sub { $concat++; bless []; },
3136 '""' => sub { $str++; "bar" };
3137
3138 my $a = "A";
3139 my $b = bless [];
3140 my $c;
3141 $c = "$a-$b";
3142 ::is($concat, 1, "RT #132801 concat count");
3143 ::is($str, 1, "RT #132801 stringify count");
3144}
3145
3146# General testing of optimising away OP_STRINGIFY, and whether
3147# OP_MULTICONCAT emulates existing behaviour.
3148#
3149# It could well be argued that the existing behaviour is buggy, but
3150# for now emulate the old behaviour.
3151#
3152# In more detail:
3153#
3154# Since 5.000, any OP_STRINGIFY immediately following an OP_CONCAT
3155# is optimised away, on the assumption that since concat will always
3156# return a valid string anyway, it doesn't need stringifying.
3157# So in "$x", the stringify is needed, but on "$x$y" it isn't.
3158# This assumption is flawed once overloading has been introduced, since
3159# concat might return an overloaded object which still needs stringifying.
3160# However, this flawed behaviour is apparently needed by at least one
3161# module, and is tested for in opbasic/concat.t: see RT #124160.
3162#
3163# There is also a wart with the OPpTARGET_MY optimisation: specifically,
3164# in $lex = "...", if $lex is a lexical var, then a chain of 2 or more
3165# concats *doesn't* optimise away OP_STRINGIFY:
3166#
3167# $lex = "$x"; # stringifies
3168# $lex = "$x$y"; # doesn't stringify
3169# $lex = "$x$y$z..."; # stringifies
3170
3171package Stringify {
3172 my $count;
3173 use overload
3174 '.' => sub {
3175 my ($a, $b, $rev) = @_;
3176 bless [ $rev ? "$b" . $a->[0] : $a->[0] . "$b" ];
3177 },
3178 '""' => sub { $count++; $_[0][0] },
3179 ;
3180
3181 for my $test(
3182 [ 1, '$pkg = "$ov"' ],
3183 [ 1, '$lex = "$ov"' ],
3184 [ 1, 'my $a = "$ov"' ],
3185 [ 1, '$pkg .= "$ov"' ],
3186 [ 1, '$lex .= "$ov"' ],
3187 [ 1, 'my $a .= "$ov"' ],
3188
3189 [ 0, '$pkg = "$ov$x"' ],
3190 [ 0, '$lex = "$ov$x"' ],
3191 [ 0, 'my $a = "$ov$x"' ],
3192 [ 0, '$pkg .= "$ov$x"' ],
3193 [ 0, '$lex .= "$ov$x"' ],
3194 [ 0, 'my $a .= "$ov$x"' ],
3195
3196 [ 0, '$pkg = "$ov$x$y"' ],
3197 [ 1, '$lex = "$ov$x$y"' ], # XXX note the anomaly
3198 [ 0, 'my $a = "$ov$x$y"' ],
3199 [ 0, '$pkg .= "$ov$x$y"' ],
3200 [ 0, '$lex .= "$ov$x$y"' ],
3201 [ 0, 'my $a .= "$ov$x$y"' ],
3202 )
3203 {
3204 my ($stringify, $code) = @$test;
3205 our $pkg = 'P';
3206 my ($ov, $x, $y, $lex) = (bless(['OV']), qw(X Y L));
3207 $count = 0;
3208 eval "$code; 1" or die $@;
3209 ::is $count, $stringify, $code;
3210 }
3211}
3212
3213# RT #133789: in multiconcat with overload, the overloaded ref returned
3214# from the overload method was being assigned to the pad targ, causing
3215# a delay to the freeing of the object
3216
3217package RT33789 {
3218 use overload
3219 '.' => sub { $_[0] }
3220 ;
3221
3222 my $destroy = 0;
3223 sub DESTROY { $destroy++ }
3224
3225 {
3226 my $o = bless [];
3227 my $result = '1' . ( '2' . ( '3' . ( '4' . ( '5' . $o ) ) ) );
3228 }
3229 ::is($destroy, 1, "RT #133789: delayed destroy");
3230}
3231
3232# GH #21477: with an overloaded object $obj, ($obj ~~ $scalar) wasn't
3233# popping the original args off the stack. So in list context, rather than
3234# returning (Y/N), it was returning ($obj, $scalar, Y/N)
3235
3236
3237package GH21477 {
3238 use overload
3239 '""' => sub { $_[0][0]; },
3240 '~~' => sub { $_[0][0] eq $_[1] },
3241 'eq' => sub { $_[0][0] eq $_[1] },
3242 ;
3243
3244 my $o = bless ['cat'];
3245
3246 # smartmatch is deprecated and will be removed in 5.042
3247 no warnings 'deprecated';
3248
3249 my @result = ($o ~~ 'cat');
3250 ::is(scalar(@result), 1, "GH #21477: return one result");
3251 ::is($result[0], 1, "GH #21477: return true");
3252
3253 @result = ($o ~~ 'dog');
3254 ::is(scalar(@result), 1, "GH #21477: return one result - part 2");
3255 ::is($result[0], "", "GH #21477: return false");
3256}