1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateBEGIN { 4*0Sstevel@tonic-gate chdir 't' if -d 't'; 5*0Sstevel@tonic-gate @INC = '../lib'; 6*0Sstevel@tonic-gate} 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gatepackage Oscalar; 9*0Sstevel@tonic-gateuse overload ( 10*0Sstevel@tonic-gate # Anonymous subroutines: 11*0Sstevel@tonic-gate'+' => sub {new Oscalar $ {$_[0]}+$_[1]}, 12*0Sstevel@tonic-gate'-' => sub {new Oscalar 13*0Sstevel@tonic-gate $_[2]? $_[1]-${$_[0]} : ${$_[0]}-$_[1]}, 14*0Sstevel@tonic-gate'<=>' => sub {new Oscalar 15*0Sstevel@tonic-gate $_[2]? $_[1]-${$_[0]} : ${$_[0]}-$_[1]}, 16*0Sstevel@tonic-gate'cmp' => sub {new Oscalar 17*0Sstevel@tonic-gate $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])}, 18*0Sstevel@tonic-gate'*' => sub {new Oscalar ${$_[0]}*$_[1]}, 19*0Sstevel@tonic-gate'/' => sub {new Oscalar 20*0Sstevel@tonic-gate $_[2]? $_[1]/${$_[0]} : 21*0Sstevel@tonic-gate ${$_[0]}/$_[1]}, 22*0Sstevel@tonic-gate'%' => sub {new Oscalar 23*0Sstevel@tonic-gate $_[2]? $_[1]%${$_[0]} : ${$_[0]}%$_[1]}, 24*0Sstevel@tonic-gate'**' => sub {new Oscalar 25*0Sstevel@tonic-gate $_[2]? $_[1]**${$_[0]} : ${$_[0]}-$_[1]}, 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gateqw( 28*0Sstevel@tonic-gate"" stringify 29*0Sstevel@tonic-gate0+ numify) # Order of arguments unsignificant 30*0Sstevel@tonic-gate); 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gatesub new { 33*0Sstevel@tonic-gate my $foo = $_[1]; 34*0Sstevel@tonic-gate bless \$foo, $_[0]; 35*0Sstevel@tonic-gate} 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gatesub stringify { "${$_[0]}" } 38*0Sstevel@tonic-gatesub numify { 0 + "${$_[0]}" } # Not needed, additional overhead 39*0Sstevel@tonic-gate # comparing to direct compilation based on 40*0Sstevel@tonic-gate # stringify 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gatepackage main; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gateour $test = 0; 45*0Sstevel@tonic-gate$| = 1; 46*0Sstevel@tonic-gateprint "1..",&last,"\n"; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gatesub test { 49*0Sstevel@tonic-gate $test++; 50*0Sstevel@tonic-gate if (@_ > 1) { 51*0Sstevel@tonic-gate my $comment = ""; 52*0Sstevel@tonic-gate $comment = " # " . $_ [2] if @_ > 2; 53*0Sstevel@tonic-gate if ($_[0] eq $_[1]) { 54*0Sstevel@tonic-gate print "ok $test$comment\n"; 55*0Sstevel@tonic-gate return 1; 56*0Sstevel@tonic-gate } else { 57*0Sstevel@tonic-gate $comment .= ": '$_[0]' ne '$_[1]'"; 58*0Sstevel@tonic-gate print "not ok $test$comment\n"; 59*0Sstevel@tonic-gate return 0; 60*0Sstevel@tonic-gate } 61*0Sstevel@tonic-gate } else { 62*0Sstevel@tonic-gate if (shift) { 63*0Sstevel@tonic-gate print "ok $test\n"; 64*0Sstevel@tonic-gate return 1; 65*0Sstevel@tonic-gate } else { 66*0Sstevel@tonic-gate print "not ok $test\n"; 67*0Sstevel@tonic-gate return 0; 68*0Sstevel@tonic-gate } 69*0Sstevel@tonic-gate } 70*0Sstevel@tonic-gate} 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate$a = new Oscalar "087"; 73*0Sstevel@tonic-gate$b= "$a"; 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate# All test numbers in comments are off by 1. 76*0Sstevel@tonic-gate# So much for hard-wiring them in :-) To fix this: 77*0Sstevel@tonic-gatetest(1); # 1 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gatetest ($b eq $a); # 2 80*0Sstevel@tonic-gatetest ($b eq "087"); # 3 81*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 4 82*0Sstevel@tonic-gatetest ($a eq $a); # 5 83*0Sstevel@tonic-gatetest ($a eq "087"); # 6 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate$c = $a + 7; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gatetest (ref $c eq "Oscalar"); # 7 88*0Sstevel@tonic-gatetest (!($c eq $a)); # 8 89*0Sstevel@tonic-gatetest ($c eq "94"); # 9 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate$b=$a; 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 10 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate$b++; 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 11 98*0Sstevel@tonic-gatetest ( $a eq "087"); # 12 99*0Sstevel@tonic-gatetest ( $b eq "88"); # 13 100*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 14 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate$c=$b; 103*0Sstevel@tonic-gate$c-=$a; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gatetest (ref $c eq "Oscalar"); # 15 106*0Sstevel@tonic-gatetest ( $a eq "087"); # 16 107*0Sstevel@tonic-gatetest ( $c eq "1"); # 17 108*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 18 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate$b=1; 111*0Sstevel@tonic-gate$b+=$a; 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 19 114*0Sstevel@tonic-gatetest ( $a eq "087"); # 20 115*0Sstevel@tonic-gatetest ( $b eq "88"); # 21 116*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 22 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gateeval q[ package Oscalar; use overload ('++' => sub { $ {$_[0]}++;$_[0] } ) ]; 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate$b=$a; 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 23 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate$b++; 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 24 127*0Sstevel@tonic-gatetest ( $a eq "087"); # 25 128*0Sstevel@tonic-gatetest ( $b eq "88"); # 26 129*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 27 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gatepackage Oscalar; 132*0Sstevel@tonic-gate$dummy=bless \$dummy; # Now cache of method should be reloaded 133*0Sstevel@tonic-gatepackage main; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate$b=$a; 136*0Sstevel@tonic-gate$b++; 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 28 139*0Sstevel@tonic-gatetest ( $a eq "087"); # 29 140*0Sstevel@tonic-gatetest ( $b eq "88"); # 30 141*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 31 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gateundef $b; # Destroying updates tables too... 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gateeval q[package Oscalar; use overload ('++' => sub { $ {$_[0]} += 2; $_[0] } ) ]; 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate$b=$a; 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 32 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate$b++; 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 33 154*0Sstevel@tonic-gatetest ( $a eq "087"); # 34 155*0Sstevel@tonic-gatetest ( $b eq "88"); # 35 156*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 36 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gatepackage Oscalar; 159*0Sstevel@tonic-gate$dummy=bless \$dummy; # Now cache of method should be reloaded 160*0Sstevel@tonic-gatepackage main; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate$b++; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 37 165*0Sstevel@tonic-gatetest ( $a eq "087"); # 38 166*0Sstevel@tonic-gatetest ( $b eq "90"); # 39 167*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 40 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate$b=$a; 170*0Sstevel@tonic-gate$b++; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 41 173*0Sstevel@tonic-gatetest ( $a eq "087"); # 42 174*0Sstevel@tonic-gatetest ( $b eq "89"); # 43 175*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 44 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gatetest ($b? 1:0); # 45 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gateeval q[ package Oscalar; use overload ('=' => sub {$main::copies++; 181*0Sstevel@tonic-gate package Oscalar; 182*0Sstevel@tonic-gate local $new=$ {$_[0]}; 183*0Sstevel@tonic-gate bless \$new } ) ]; 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate$b=new Oscalar "$a"; 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 46 188*0Sstevel@tonic-gatetest ( $a eq "087"); # 47 189*0Sstevel@tonic-gatetest ( $b eq "087"); # 48 190*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 49 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate$b++; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 50 195*0Sstevel@tonic-gatetest ( $a eq "087"); # 51 196*0Sstevel@tonic-gatetest ( $b eq "89"); # 52 197*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 53 198*0Sstevel@tonic-gatetest ($copies == 0); # 54 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate$b+=1; 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 55 203*0Sstevel@tonic-gatetest ( $a eq "087"); # 56 204*0Sstevel@tonic-gatetest ( $b eq "90"); # 57 205*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 58 206*0Sstevel@tonic-gatetest ($copies == 0); # 59 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate$b=$a; 209*0Sstevel@tonic-gate$b+=1; 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 60 212*0Sstevel@tonic-gatetest ( $a eq "087"); # 61 213*0Sstevel@tonic-gatetest ( $b eq "88"); # 62 214*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 63 215*0Sstevel@tonic-gatetest ($copies == 0); # 64 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate$b=$a; 218*0Sstevel@tonic-gate$b++; 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gatetest (ref $b eq "Oscalar") || print ref $b,"=ref(b)\n"; # 65 221*0Sstevel@tonic-gatetest ( $a eq "087"); # 66 222*0Sstevel@tonic-gatetest ( $b eq "89"); # 67 223*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 68 224*0Sstevel@tonic-gatetest ($copies == 1); # 69 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gateeval q[package Oscalar; use overload ('+=' => sub {$ {$_[0]} += 3*$_[1]; 227*0Sstevel@tonic-gate $_[0] } ) ]; 228*0Sstevel@tonic-gate$c=new Oscalar; # Cause rehash 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate$b=$a; 231*0Sstevel@tonic-gate$b+=1; 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 70 234*0Sstevel@tonic-gatetest ( $a eq "087"); # 71 235*0Sstevel@tonic-gatetest ( $b eq "90"); # 72 236*0Sstevel@tonic-gatetest (ref $a eq "Oscalar"); # 73 237*0Sstevel@tonic-gatetest ($copies == 2); # 74 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate$b+=$b; 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 75 242*0Sstevel@tonic-gatetest ( $b eq "360"); # 76 243*0Sstevel@tonic-gatetest ($copies == 2); # 77 244*0Sstevel@tonic-gate$b=-$b; 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 78 247*0Sstevel@tonic-gatetest ( $b eq "-360"); # 79 248*0Sstevel@tonic-gatetest ($copies == 2); # 80 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate$b=abs($b); 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 81 253*0Sstevel@tonic-gatetest ( $b eq "360"); # 82 254*0Sstevel@tonic-gatetest ($copies == 2); # 83 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate$b=abs($b); 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gatetest (ref $b eq "Oscalar"); # 84 259*0Sstevel@tonic-gatetest ( $b eq "360"); # 85 260*0Sstevel@tonic-gatetest ($copies == 2); # 86 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gateeval q[package Oscalar; 263*0Sstevel@tonic-gate use overload ('x' => sub {new Oscalar ( $_[2] ? "_.$_[1]._" x $ {$_[0]} 264*0Sstevel@tonic-gate : "_.${$_[0]}._" x $_[1])}) ]; 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate$a=new Oscalar "yy"; 267*0Sstevel@tonic-gate$a x= 3; 268*0Sstevel@tonic-gatetest ($a eq "_.yy.__.yy.__.yy._"); # 87 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gateeval q[package Oscalar; 271*0Sstevel@tonic-gate use overload ('.' => sub {new Oscalar ( $_[2] ? 272*0Sstevel@tonic-gate "_.$_[1].__.$ {$_[0]}._" 273*0Sstevel@tonic-gate : "_.$ {$_[0]}.__.$_[1]._")}) ]; 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate$a=new Oscalar "xx"; 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gatetest ("b${a}c" eq "_._.b.__.xx._.__.c._"); # 88 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate# Check inheritance of overloading; 280*0Sstevel@tonic-gate{ 281*0Sstevel@tonic-gate package OscalarI; 282*0Sstevel@tonic-gate @ISA = 'Oscalar'; 283*0Sstevel@tonic-gate} 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate$aI = new OscalarI "$a"; 286*0Sstevel@tonic-gatetest (ref $aI eq "OscalarI"); # 89 287*0Sstevel@tonic-gatetest ("$aI" eq "xx"); # 90 288*0Sstevel@tonic-gatetest ($aI eq "xx"); # 91 289*0Sstevel@tonic-gatetest ("b${aI}c" eq "_._.b.__.xx._.__.c._"); # 92 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate# Here we test blessing to a package updates hash 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gateeval "package Oscalar; no overload '.'"; 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gatetest ("b${a}" eq "_.b.__.xx._"); # 93 296*0Sstevel@tonic-gate$x="1"; 297*0Sstevel@tonic-gatebless \$x, Oscalar; 298*0Sstevel@tonic-gatetest ("b${a}c" eq "bxxc"); # 94 299*0Sstevel@tonic-gatenew Oscalar 1; 300*0Sstevel@tonic-gatetest ("b${a}c" eq "bxxc"); # 95 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate# Negative overloading: 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate$na = eval { ~$a }; 305*0Sstevel@tonic-gatetest($@ =~ /no method found/); # 96 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate# Check AUTOLOADING: 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate*Oscalar::AUTOLOAD = 310*0Sstevel@tonic-gate sub { *{"Oscalar::$AUTOLOAD"} = sub {"_!_" . shift() . "_!_"} ; 311*0Sstevel@tonic-gate goto &{"Oscalar::$AUTOLOAD"}}; 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gateeval "package Oscalar; sub comple; use overload '~' => 'comple'"; 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate$na = eval { ~$a }; # Hash was not updated 316*0Sstevel@tonic-gatetest($@ =~ /no method found/); # 97 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gatebless \$x, Oscalar; 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate$na = eval { ~$a }; # Hash updated 321*0Sstevel@tonic-gatewarn "`$na', $@" if $@; 322*0Sstevel@tonic-gatetest !$@; # 98 323*0Sstevel@tonic-gatetest($na eq '_!_xx_!_'); # 99 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate$na = 0; 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate$na = eval { ~$aI }; # Hash was not updated 328*0Sstevel@tonic-gatetest($@ =~ /no method found/); # 100 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gatebless \$x, OscalarI; 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate$na = eval { ~$aI }; 333*0Sstevel@tonic-gateprint $@; 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gatetest !$@; # 101 336*0Sstevel@tonic-gatetest($na eq '_!_xx_!_'); # 102 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gateeval "package Oscalar; sub rshft; use overload '>>' => 'rshft'"; 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate$na = eval { $aI >> 1 }; # Hash was not updated 341*0Sstevel@tonic-gatetest($@ =~ /no method found/); # 103 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gatebless \$x, OscalarI; 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate$na = 0; 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate$na = eval { $aI >> 1 }; 348*0Sstevel@tonic-gateprint $@; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gatetest !$@; # 104 351*0Sstevel@tonic-gatetest($na eq '_!_xx_!_'); # 105 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate# warn overload::Method($a, '0+'), "\n"; 354*0Sstevel@tonic-gatetest (overload::Method($a, '0+') eq \&Oscalar::numify); # 106 355*0Sstevel@tonic-gatetest (overload::Method($aI,'0+') eq \&Oscalar::numify); # 107 356*0Sstevel@tonic-gatetest (overload::Overloaded($aI)); # 108 357*0Sstevel@tonic-gatetest (!overload::Overloaded('overload')); # 109 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gatetest (! defined overload::Method($aI, '<<')); # 110 360*0Sstevel@tonic-gatetest (! defined overload::Method($a, '<')); # 111 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gatetest (overload::StrVal($aI) =~ /^OscalarI=SCALAR\(0x[\da-fA-F]+\)$/); # 112 363*0Sstevel@tonic-gatetest (overload::StrVal(\$aI) eq "@{[\$aI]}"); # 113 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate# Check overloading by methods (specified deep in the ISA tree). 366*0Sstevel@tonic-gate{ 367*0Sstevel@tonic-gate package OscalarII; 368*0Sstevel@tonic-gate @ISA = 'OscalarI'; 369*0Sstevel@tonic-gate sub Oscalar::lshft {"_<<_" . shift() . "_<<_"} 370*0Sstevel@tonic-gate eval "package OscalarI; use overload '<<' => 'lshft', '|' => 'lshft'"; 371*0Sstevel@tonic-gate} 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate$aaII = "087"; 374*0Sstevel@tonic-gate$aII = \$aaII; 375*0Sstevel@tonic-gatebless $aII, 'OscalarII'; 376*0Sstevel@tonic-gatebless \$fake, 'OscalarI'; # update the hash 377*0Sstevel@tonic-gatetest(($aI | 3) eq '_<<_xx_<<_'); # 114 378*0Sstevel@tonic-gate# warn $aII << 3; 379*0Sstevel@tonic-gatetest(($aII << 3) eq '_<<_087_<<_'); # 115 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate{ 382*0Sstevel@tonic-gate BEGIN { $int = 7; overload::constant 'integer' => sub {$int++; shift}; } 383*0Sstevel@tonic-gate $out = 2**10; 384*0Sstevel@tonic-gate} 385*0Sstevel@tonic-gatetest($int, 9); # 116 386*0Sstevel@tonic-gatetest($out, 1024); # 117 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate$foo = 'foo'; 389*0Sstevel@tonic-gate$foo1 = 'f\'o\\o'; 390*0Sstevel@tonic-gate{ 391*0Sstevel@tonic-gate BEGIN { $q = $qr = 7; 392*0Sstevel@tonic-gate overload::constant 'q' => sub {$q++; push @q, shift, ($_[1] || 'none'); shift}, 393*0Sstevel@tonic-gate 'qr' => sub {$qr++; push @qr, shift, ($_[1] || 'none'); shift}; } 394*0Sstevel@tonic-gate $out = 'foo'; 395*0Sstevel@tonic-gate $out1 = 'f\'o\\o'; 396*0Sstevel@tonic-gate $out2 = "a\a$foo,\,"; 397*0Sstevel@tonic-gate /b\b$foo.\./; 398*0Sstevel@tonic-gate} 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gatetest($out, 'foo'); # 118 401*0Sstevel@tonic-gatetest($out, $foo); # 119 402*0Sstevel@tonic-gatetest($out1, 'f\'o\\o'); # 120 403*0Sstevel@tonic-gatetest($out1, $foo1); # 121 404*0Sstevel@tonic-gatetest($out2, "a\afoo,\,"); # 122 405*0Sstevel@tonic-gatetest("@q", "foo q f'o\\\\o q a\\a qq ,\\, qq"); # 123 406*0Sstevel@tonic-gatetest($q, 11); # 124 407*0Sstevel@tonic-gatetest("@qr", "b\\b qq .\\. qq"); # 125 408*0Sstevel@tonic-gatetest($qr, 9); # 126 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate{ 411*0Sstevel@tonic-gate $_ = '!<b>!foo!<-.>!'; 412*0Sstevel@tonic-gate BEGIN { overload::constant 'q' => sub {push @q1, shift, ($_[1] || 'none'); "_<" . (shift) . ">_"}, 413*0Sstevel@tonic-gate 'qr' => sub {push @qr1, shift, ($_[1] || 'none'); "!<" . (shift) . ">!"}; } 414*0Sstevel@tonic-gate $out = 'foo'; 415*0Sstevel@tonic-gate $out1 = 'f\'o\\o'; 416*0Sstevel@tonic-gate $out2 = "a\a$foo,\,"; 417*0Sstevel@tonic-gate $res = /b\b$foo.\./; 418*0Sstevel@tonic-gate $a = <<EOF; 419*0Sstevel@tonic-gateoups 420*0Sstevel@tonic-gateEOF 421*0Sstevel@tonic-gate $b = <<'EOF'; 422*0Sstevel@tonic-gateoups1 423*0Sstevel@tonic-gateEOF 424*0Sstevel@tonic-gate $c = bareword; 425*0Sstevel@tonic-gate m'try it'; 426*0Sstevel@tonic-gate s'first part'second part'; 427*0Sstevel@tonic-gate s/yet another/tail here/; 428*0Sstevel@tonic-gate tr/A-Z/a-z/; 429*0Sstevel@tonic-gate} 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gatetest($out, '_<foo>_'); # 117 432*0Sstevel@tonic-gatetest($out1, '_<f\'o\\o>_'); # 128 433*0Sstevel@tonic-gatetest($out2, "_<a\a>_foo_<,\,>_"); # 129 434*0Sstevel@tonic-gatetest("@q1", "foo q f'o\\\\o q a\\a qq ,\\, qq oups 435*0Sstevel@tonic-gate qq oups1 436*0Sstevel@tonic-gate q second part q tail here s A-Z tr a-z tr"); # 130 437*0Sstevel@tonic-gatetest("@qr1", "b\\b qq .\\. qq try it q first part q yet another qq"); # 131 438*0Sstevel@tonic-gatetest($res, 1); # 132 439*0Sstevel@tonic-gatetest($a, "_<oups 440*0Sstevel@tonic-gate>_"); # 133 441*0Sstevel@tonic-gatetest($b, "_<oups1 442*0Sstevel@tonic-gate>_"); # 134 443*0Sstevel@tonic-gatetest($c, "bareword"); # 135 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate{ 446*0Sstevel@tonic-gate package symbolic; # Primitive symbolic calculator 447*0Sstevel@tonic-gate use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num, 448*0Sstevel@tonic-gate '=' => \&cpy, '++' => \&inc, '--' => \&dec; 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate sub new { shift; bless ['n', @_] } 451*0Sstevel@tonic-gate sub cpy { 452*0Sstevel@tonic-gate my $self = shift; 453*0Sstevel@tonic-gate bless [@$self], ref $self; 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate sub inc { $_[0] = bless ['++', $_[0], 1]; } 456*0Sstevel@tonic-gate sub dec { $_[0] = bless ['--', $_[0], 1]; } 457*0Sstevel@tonic-gate sub wrap { 458*0Sstevel@tonic-gate my ($obj, $other, $inv, $meth) = @_; 459*0Sstevel@tonic-gate if ($meth eq '++' or $meth eq '--') { 460*0Sstevel@tonic-gate @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference 461*0Sstevel@tonic-gate return $obj; 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate ($obj, $other) = ($other, $obj) if $inv; 464*0Sstevel@tonic-gate bless [$meth, $obj, $other]; 465*0Sstevel@tonic-gate } 466*0Sstevel@tonic-gate sub str { 467*0Sstevel@tonic-gate my ($meth, $a, $b) = @{+shift}; 468*0Sstevel@tonic-gate $a = 'u' unless defined $a; 469*0Sstevel@tonic-gate if (defined $b) { 470*0Sstevel@tonic-gate "[$meth $a $b]"; 471*0Sstevel@tonic-gate } else { 472*0Sstevel@tonic-gate "[$meth $a]"; 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate } 475*0Sstevel@tonic-gate my %subr = ( 'n' => sub {$_[0]} ); 476*0Sstevel@tonic-gate foreach my $op (split " ", $overload::ops{with_assign}) { 477*0Sstevel@tonic-gate $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}"; 478*0Sstevel@tonic-gate } 479*0Sstevel@tonic-gate my @bins = qw(binary 3way_comparison num_comparison str_comparison); 480*0Sstevel@tonic-gate foreach my $op (split " ", "@overload::ops{ @bins }") { 481*0Sstevel@tonic-gate $subr{$op} = eval "sub {shift() $op shift()}"; 482*0Sstevel@tonic-gate } 483*0Sstevel@tonic-gate foreach my $op (split " ", "@overload::ops{qw(unary func)}") { 484*0Sstevel@tonic-gate $subr{$op} = eval "sub {$op shift()}"; 485*0Sstevel@tonic-gate } 486*0Sstevel@tonic-gate $subr{'++'} = $subr{'+'}; 487*0Sstevel@tonic-gate $subr{'--'} = $subr{'-'}; 488*0Sstevel@tonic-gate 489*0Sstevel@tonic-gate sub num { 490*0Sstevel@tonic-gate my ($meth, $a, $b) = @{+shift}; 491*0Sstevel@tonic-gate my $subr = $subr{$meth} 492*0Sstevel@tonic-gate or die "Do not know how to ($meth) in symbolic"; 493*0Sstevel@tonic-gate $a = $a->num if ref $a eq __PACKAGE__; 494*0Sstevel@tonic-gate $b = $b->num if ref $b eq __PACKAGE__; 495*0Sstevel@tonic-gate $subr->($a,$b); 496*0Sstevel@tonic-gate } 497*0Sstevel@tonic-gate sub TIESCALAR { my $pack = shift; $pack->new(@_) } 498*0Sstevel@tonic-gate sub FETCH { shift } 499*0Sstevel@tonic-gate sub nop { } # Around a bug 500*0Sstevel@tonic-gate sub vars { my $p = shift; tie($_, $p), $_->nop foreach @_; } 501*0Sstevel@tonic-gate sub STORE { 502*0Sstevel@tonic-gate my $obj = shift; 503*0Sstevel@tonic-gate $#$obj = 1; 504*0Sstevel@tonic-gate $obj->[1] = shift; 505*0Sstevel@tonic-gate } 506*0Sstevel@tonic-gate} 507*0Sstevel@tonic-gate 508*0Sstevel@tonic-gate{ 509*0Sstevel@tonic-gate my $foo = new symbolic 11; 510*0Sstevel@tonic-gate my $baz = $foo++; 511*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '12'); 512*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '11'); 513*0Sstevel@tonic-gate my $bar = $foo; 514*0Sstevel@tonic-gate $baz = ++$foo; 515*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '13'); 516*0Sstevel@tonic-gate test( (sprintf "%d", $bar), '12'); 517*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '13'); 518*0Sstevel@tonic-gate my $ban = $foo; 519*0Sstevel@tonic-gate $baz = ($foo += 1); 520*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '14'); 521*0Sstevel@tonic-gate test( (sprintf "%d", $bar), '12'); 522*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '14'); 523*0Sstevel@tonic-gate test( (sprintf "%d", $ban), '13'); 524*0Sstevel@tonic-gate $baz = 0; 525*0Sstevel@tonic-gate $baz = $foo++; 526*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '15'); 527*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '14'); 528*0Sstevel@tonic-gate test( "$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]'); 529*0Sstevel@tonic-gate} 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate{ 532*0Sstevel@tonic-gate my $iter = new symbolic 2; 533*0Sstevel@tonic-gate my $side = new symbolic 1; 534*0Sstevel@tonic-gate my $cnt = $iter; 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gate while ($cnt) { 537*0Sstevel@tonic-gate $cnt = $cnt - 1; # The "simple" way 538*0Sstevel@tonic-gate $side = (sqrt(1 + $side**2) - 1)/$side; 539*0Sstevel@tonic-gate } 540*0Sstevel@tonic-gate my $pi = $side*(2**($iter+2)); 541*0Sstevel@tonic-gate test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; 542*0Sstevel@tonic-gate test( (sprintf "%f", $pi), '3.182598'); 543*0Sstevel@tonic-gate} 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate{ 546*0Sstevel@tonic-gate my $iter = new symbolic 2; 547*0Sstevel@tonic-gate my $side = new symbolic 1; 548*0Sstevel@tonic-gate my $cnt = $iter; 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate while ($cnt--) { 551*0Sstevel@tonic-gate $side = (sqrt(1 + $side**2) - 1)/$side; 552*0Sstevel@tonic-gate } 553*0Sstevel@tonic-gate my $pi = $side*(2**($iter+2)); 554*0Sstevel@tonic-gate test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; 555*0Sstevel@tonic-gate test( (sprintf "%f", $pi), '3.182598'); 556*0Sstevel@tonic-gate} 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate{ 559*0Sstevel@tonic-gate my ($a, $b); 560*0Sstevel@tonic-gate symbolic->vars($a, $b); 561*0Sstevel@tonic-gate my $c = sqrt($a**2 + $b**2); 562*0Sstevel@tonic-gate $a = 3; $b = 4; 563*0Sstevel@tonic-gate test( (sprintf "%d", $c), '5'); 564*0Sstevel@tonic-gate $a = 12; $b = 5; 565*0Sstevel@tonic-gate test( (sprintf "%d", $c), '13'); 566*0Sstevel@tonic-gate} 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate{ 569*0Sstevel@tonic-gate package symbolic1; # Primitive symbolic calculator 570*0Sstevel@tonic-gate # Mutator inc/dec 571*0Sstevel@tonic-gate use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num, '=' => \&cpy; 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate sub new { shift; bless ['n', @_] } 574*0Sstevel@tonic-gate sub cpy { 575*0Sstevel@tonic-gate my $self = shift; 576*0Sstevel@tonic-gate bless [@$self], ref $self; 577*0Sstevel@tonic-gate } 578*0Sstevel@tonic-gate sub wrap { 579*0Sstevel@tonic-gate my ($obj, $other, $inv, $meth) = @_; 580*0Sstevel@tonic-gate if ($meth eq '++' or $meth eq '--') { 581*0Sstevel@tonic-gate @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference 582*0Sstevel@tonic-gate return $obj; 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate ($obj, $other) = ($other, $obj) if $inv; 585*0Sstevel@tonic-gate bless [$meth, $obj, $other]; 586*0Sstevel@tonic-gate } 587*0Sstevel@tonic-gate sub str { 588*0Sstevel@tonic-gate my ($meth, $a, $b) = @{+shift}; 589*0Sstevel@tonic-gate $a = 'u' unless defined $a; 590*0Sstevel@tonic-gate if (defined $b) { 591*0Sstevel@tonic-gate "[$meth $a $b]"; 592*0Sstevel@tonic-gate } else { 593*0Sstevel@tonic-gate "[$meth $a]"; 594*0Sstevel@tonic-gate } 595*0Sstevel@tonic-gate } 596*0Sstevel@tonic-gate my %subr = ( 'n' => sub {$_[0]} ); 597*0Sstevel@tonic-gate foreach my $op (split " ", $overload::ops{with_assign}) { 598*0Sstevel@tonic-gate $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}"; 599*0Sstevel@tonic-gate } 600*0Sstevel@tonic-gate my @bins = qw(binary 3way_comparison num_comparison str_comparison); 601*0Sstevel@tonic-gate foreach my $op (split " ", "@overload::ops{ @bins }") { 602*0Sstevel@tonic-gate $subr{$op} = eval "sub {shift() $op shift()}"; 603*0Sstevel@tonic-gate } 604*0Sstevel@tonic-gate foreach my $op (split " ", "@overload::ops{qw(unary func)}") { 605*0Sstevel@tonic-gate $subr{$op} = eval "sub {$op shift()}"; 606*0Sstevel@tonic-gate } 607*0Sstevel@tonic-gate $subr{'++'} = $subr{'+'}; 608*0Sstevel@tonic-gate $subr{'--'} = $subr{'-'}; 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate sub num { 611*0Sstevel@tonic-gate my ($meth, $a, $b) = @{+shift}; 612*0Sstevel@tonic-gate my $subr = $subr{$meth} 613*0Sstevel@tonic-gate or die "Do not know how to ($meth) in symbolic"; 614*0Sstevel@tonic-gate $a = $a->num if ref $a eq __PACKAGE__; 615*0Sstevel@tonic-gate $b = $b->num if ref $b eq __PACKAGE__; 616*0Sstevel@tonic-gate $subr->($a,$b); 617*0Sstevel@tonic-gate } 618*0Sstevel@tonic-gate sub TIESCALAR { my $pack = shift; $pack->new(@_) } 619*0Sstevel@tonic-gate sub FETCH { shift } 620*0Sstevel@tonic-gate sub nop { } # Around a bug 621*0Sstevel@tonic-gate sub vars { my $p = shift; tie($_, $p), $_->nop foreach @_; } 622*0Sstevel@tonic-gate sub STORE { 623*0Sstevel@tonic-gate my $obj = shift; 624*0Sstevel@tonic-gate $#$obj = 1; 625*0Sstevel@tonic-gate $obj->[1] = shift; 626*0Sstevel@tonic-gate } 627*0Sstevel@tonic-gate} 628*0Sstevel@tonic-gate 629*0Sstevel@tonic-gate{ 630*0Sstevel@tonic-gate my $foo = new symbolic1 11; 631*0Sstevel@tonic-gate my $baz = $foo++; 632*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '12'); 633*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '11'); 634*0Sstevel@tonic-gate my $bar = $foo; 635*0Sstevel@tonic-gate $baz = ++$foo; 636*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '13'); 637*0Sstevel@tonic-gate test( (sprintf "%d", $bar), '12'); 638*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '13'); 639*0Sstevel@tonic-gate my $ban = $foo; 640*0Sstevel@tonic-gate $baz = ($foo += 1); 641*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '14'); 642*0Sstevel@tonic-gate test( (sprintf "%d", $bar), '12'); 643*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '14'); 644*0Sstevel@tonic-gate test( (sprintf "%d", $ban), '13'); 645*0Sstevel@tonic-gate $baz = 0; 646*0Sstevel@tonic-gate $baz = $foo++; 647*0Sstevel@tonic-gate test( (sprintf "%d", $foo), '15'); 648*0Sstevel@tonic-gate test( (sprintf "%d", $baz), '14'); 649*0Sstevel@tonic-gate test( "$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]'); 650*0Sstevel@tonic-gate} 651*0Sstevel@tonic-gate 652*0Sstevel@tonic-gate{ 653*0Sstevel@tonic-gate my $iter = new symbolic1 2; 654*0Sstevel@tonic-gate my $side = new symbolic1 1; 655*0Sstevel@tonic-gate my $cnt = $iter; 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gate while ($cnt) { 658*0Sstevel@tonic-gate $cnt = $cnt - 1; # The "simple" way 659*0Sstevel@tonic-gate $side = (sqrt(1 + $side**2) - 1)/$side; 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate my $pi = $side*(2**($iter+2)); 662*0Sstevel@tonic-gate test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; 663*0Sstevel@tonic-gate test( (sprintf "%f", $pi), '3.182598'); 664*0Sstevel@tonic-gate} 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate{ 667*0Sstevel@tonic-gate my $iter = new symbolic1 2; 668*0Sstevel@tonic-gate my $side = new symbolic1 1; 669*0Sstevel@tonic-gate my $cnt = $iter; 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate while ($cnt--) { 672*0Sstevel@tonic-gate $side = (sqrt(1 + $side**2) - 1)/$side; 673*0Sstevel@tonic-gate } 674*0Sstevel@tonic-gate my $pi = $side*(2**($iter+2)); 675*0Sstevel@tonic-gate test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]'; 676*0Sstevel@tonic-gate test( (sprintf "%f", $pi), '3.182598'); 677*0Sstevel@tonic-gate} 678*0Sstevel@tonic-gate 679*0Sstevel@tonic-gate{ 680*0Sstevel@tonic-gate my ($a, $b); 681*0Sstevel@tonic-gate symbolic1->vars($a, $b); 682*0Sstevel@tonic-gate my $c = sqrt($a**2 + $b**2); 683*0Sstevel@tonic-gate $a = 3; $b = 4; 684*0Sstevel@tonic-gate test( (sprintf "%d", $c), '5'); 685*0Sstevel@tonic-gate $a = 12; $b = 5; 686*0Sstevel@tonic-gate test( (sprintf "%d", $c), '13'); 687*0Sstevel@tonic-gate} 688*0Sstevel@tonic-gate 689*0Sstevel@tonic-gate{ 690*0Sstevel@tonic-gate package two_face; # Scalars with separate string and 691*0Sstevel@tonic-gate # numeric values. 692*0Sstevel@tonic-gate sub new { my $p = shift; bless [@_], $p } 693*0Sstevel@tonic-gate use overload '""' => \&str, '0+' => \&num, fallback => 1; 694*0Sstevel@tonic-gate sub num {shift->[1]} 695*0Sstevel@tonic-gate sub str {shift->[0]} 696*0Sstevel@tonic-gate} 697*0Sstevel@tonic-gate 698*0Sstevel@tonic-gate{ 699*0Sstevel@tonic-gate my $seven = new two_face ("vii", 7); 700*0Sstevel@tonic-gate test( (sprintf "seven=$seven, seven=%d, eight=%d", $seven, $seven+1), 701*0Sstevel@tonic-gate 'seven=vii, seven=7, eight=8'); 702*0Sstevel@tonic-gate test( scalar ($seven =~ /i/), '1') 703*0Sstevel@tonic-gate} 704*0Sstevel@tonic-gate 705*0Sstevel@tonic-gate{ 706*0Sstevel@tonic-gate package sorting; 707*0Sstevel@tonic-gate use overload 'cmp' => \∁ 708*0Sstevel@tonic-gate sub new { my ($p, $v) = @_; bless \$v, $p } 709*0Sstevel@tonic-gate sub comp { my ($x,$y) = @_; ($$x * 3 % 10) <=> ($$y * 3 % 10) or $$x cmp $$y } 710*0Sstevel@tonic-gate} 711*0Sstevel@tonic-gate{ 712*0Sstevel@tonic-gate my @arr = map sorting->new($_), 0..12; 713*0Sstevel@tonic-gate my @sorted1 = sort @arr; 714*0Sstevel@tonic-gate my @sorted2 = map $$_, @sorted1; 715*0Sstevel@tonic-gate test "@sorted2", '0 10 7 4 1 11 8 5 12 2 9 6 3'; 716*0Sstevel@tonic-gate} 717*0Sstevel@tonic-gate{ 718*0Sstevel@tonic-gate package iterator; 719*0Sstevel@tonic-gate use overload '<>' => \&iter; 720*0Sstevel@tonic-gate sub new { my ($p, $v) = @_; bless \$v, $p } 721*0Sstevel@tonic-gate sub iter { my ($x) = @_; return undef if $$x < 0; return $$x--; } 722*0Sstevel@tonic-gate} 723*0Sstevel@tonic-gate 724*0Sstevel@tonic-gate# XXX iterator overload not intended to work with CORE::GLOBAL? 725*0Sstevel@tonic-gateif (defined &CORE::GLOBAL::glob) { 726*0Sstevel@tonic-gate test '1', '1'; # 175 727*0Sstevel@tonic-gate test '1', '1'; # 176 728*0Sstevel@tonic-gate test '1', '1'; # 177 729*0Sstevel@tonic-gate} 730*0Sstevel@tonic-gateelse { 731*0Sstevel@tonic-gate my $iter = iterator->new(5); 732*0Sstevel@tonic-gate my $acc = ''; 733*0Sstevel@tonic-gate my $out; 734*0Sstevel@tonic-gate $acc .= " $out" while $out = <${iter}>; 735*0Sstevel@tonic-gate test $acc, ' 5 4 3 2 1 0'; # 175 736*0Sstevel@tonic-gate $iter = iterator->new(5); 737*0Sstevel@tonic-gate test scalar <${iter}>, '5'; # 176 738*0Sstevel@tonic-gate $acc = ''; 739*0Sstevel@tonic-gate $acc .= " $out" while $out = <$iter>; 740*0Sstevel@tonic-gate test $acc, ' 4 3 2 1 0'; # 177 741*0Sstevel@tonic-gate} 742*0Sstevel@tonic-gate{ 743*0Sstevel@tonic-gate package deref; 744*0Sstevel@tonic-gate use overload '%{}' => \&hderef, '&{}' => \&cderef, 745*0Sstevel@tonic-gate '*{}' => \&gderef, '${}' => \&sderef, '@{}' => \&aderef; 746*0Sstevel@tonic-gate sub new { my ($p, $v) = @_; bless \$v, $p } 747*0Sstevel@tonic-gate sub deref { 748*0Sstevel@tonic-gate my ($self, $key) = (shift, shift); 749*0Sstevel@tonic-gate my $class = ref $self; 750*0Sstevel@tonic-gate bless $self, 'deref::dummy'; # Disable overloading of %{} 751*0Sstevel@tonic-gate my $out = $self->{$key}; 752*0Sstevel@tonic-gate bless $self, $class; # Restore overloading 753*0Sstevel@tonic-gate $out; 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate sub hderef {shift->deref('h')} 756*0Sstevel@tonic-gate sub aderef {shift->deref('a')} 757*0Sstevel@tonic-gate sub cderef {shift->deref('c')} 758*0Sstevel@tonic-gate sub gderef {shift->deref('g')} 759*0Sstevel@tonic-gate sub sderef {shift->deref('s')} 760*0Sstevel@tonic-gate} 761*0Sstevel@tonic-gate{ 762*0Sstevel@tonic-gate my $deref = bless { h => { foo => 5 , fake => 23 }, 763*0Sstevel@tonic-gate c => sub {return shift() + 34}, 764*0Sstevel@tonic-gate 's' => \123, 765*0Sstevel@tonic-gate a => [11..13], 766*0Sstevel@tonic-gate g => \*srt, 767*0Sstevel@tonic-gate }, 'deref'; 768*0Sstevel@tonic-gate # Hash: 769*0Sstevel@tonic-gate my @cont = sort %$deref; 770*0Sstevel@tonic-gate if ("\t" eq "\011") { # ascii 771*0Sstevel@tonic-gate test "@cont", '23 5 fake foo'; # 178 772*0Sstevel@tonic-gate } 773*0Sstevel@tonic-gate else { # ebcdic alpha-numeric sort order 774*0Sstevel@tonic-gate test "@cont", 'fake foo 23 5'; # 178 775*0Sstevel@tonic-gate } 776*0Sstevel@tonic-gate my @keys = sort keys %$deref; 777*0Sstevel@tonic-gate test "@keys", 'fake foo'; # 179 778*0Sstevel@tonic-gate my @val = sort values %$deref; 779*0Sstevel@tonic-gate test "@val", '23 5'; # 180 780*0Sstevel@tonic-gate test $deref->{foo}, 5; # 181 781*0Sstevel@tonic-gate test defined $deref->{bar}, ''; # 182 782*0Sstevel@tonic-gate my $key; 783*0Sstevel@tonic-gate @keys = (); 784*0Sstevel@tonic-gate push @keys, $key while $key = each %$deref; 785*0Sstevel@tonic-gate @keys = sort @keys; 786*0Sstevel@tonic-gate test "@keys", 'fake foo'; # 183 787*0Sstevel@tonic-gate test exists $deref->{bar}, ''; # 184 788*0Sstevel@tonic-gate test exists $deref->{foo}, 1; # 185 789*0Sstevel@tonic-gate # Code: 790*0Sstevel@tonic-gate test $deref->(5), 39; # 186 791*0Sstevel@tonic-gate test &$deref(6), 40; # 187 792*0Sstevel@tonic-gate sub xxx_goto { goto &$deref } 793*0Sstevel@tonic-gate test xxx_goto(7), 41; # 188 794*0Sstevel@tonic-gate my $srt = bless { c => sub {$b <=> $a} 795*0Sstevel@tonic-gate }, 'deref'; 796*0Sstevel@tonic-gate *srt = \&$srt; 797*0Sstevel@tonic-gate my @sorted = sort srt 11, 2, 5, 1, 22; 798*0Sstevel@tonic-gate test "@sorted", '22 11 5 2 1'; # 189 799*0Sstevel@tonic-gate # Scalar 800*0Sstevel@tonic-gate test $$deref, 123; # 190 801*0Sstevel@tonic-gate # Code 802*0Sstevel@tonic-gate @sorted = sort $srt 11, 2, 5, 1, 22; 803*0Sstevel@tonic-gate test "@sorted", '22 11 5 2 1'; # 191 804*0Sstevel@tonic-gate # Array 805*0Sstevel@tonic-gate test "@$deref", '11 12 13'; # 192 806*0Sstevel@tonic-gate test $#$deref, '2'; # 193 807*0Sstevel@tonic-gate my $l = @$deref; 808*0Sstevel@tonic-gate test $l, 3; # 194 809*0Sstevel@tonic-gate test $deref->[2], '13'; # 195 810*0Sstevel@tonic-gate $l = pop @$deref; 811*0Sstevel@tonic-gate test $l, 13; # 196 812*0Sstevel@tonic-gate $l = 1; 813*0Sstevel@tonic-gate test $deref->[$l], '12'; # 197 814*0Sstevel@tonic-gate # Repeated dereference 815*0Sstevel@tonic-gate my $double = bless { h => $deref, 816*0Sstevel@tonic-gate }, 'deref'; 817*0Sstevel@tonic-gate test $double->{foo}, 5; # 198 818*0Sstevel@tonic-gate} 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate{ 821*0Sstevel@tonic-gate package two_refs; 822*0Sstevel@tonic-gate use overload '%{}' => \&gethash, '@{}' => sub { ${shift()} }; 823*0Sstevel@tonic-gate sub new { 824*0Sstevel@tonic-gate my $p = shift; 825*0Sstevel@tonic-gate bless \ [@_], $p; 826*0Sstevel@tonic-gate } 827*0Sstevel@tonic-gate sub gethash { 828*0Sstevel@tonic-gate my %h; 829*0Sstevel@tonic-gate my $self = shift; 830*0Sstevel@tonic-gate tie %h, ref $self, $self; 831*0Sstevel@tonic-gate \%h; 832*0Sstevel@tonic-gate } 833*0Sstevel@tonic-gate 834*0Sstevel@tonic-gate sub TIEHASH { my $p = shift; bless \ shift, $p } 835*0Sstevel@tonic-gate my %fields; 836*0Sstevel@tonic-gate my $i = 0; 837*0Sstevel@tonic-gate $fields{$_} = $i++ foreach qw{zero one two three}; 838*0Sstevel@tonic-gate sub STORE { 839*0Sstevel@tonic-gate my $self = ${shift()}; 840*0Sstevel@tonic-gate my $key = $fields{shift()}; 841*0Sstevel@tonic-gate defined $key or die "Out of band access"; 842*0Sstevel@tonic-gate $$self->[$key] = shift; 843*0Sstevel@tonic-gate } 844*0Sstevel@tonic-gate sub FETCH { 845*0Sstevel@tonic-gate my $self = ${shift()}; 846*0Sstevel@tonic-gate my $key = $fields{shift()}; 847*0Sstevel@tonic-gate defined $key or die "Out of band access"; 848*0Sstevel@tonic-gate $$self->[$key]; 849*0Sstevel@tonic-gate } 850*0Sstevel@tonic-gate} 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gatemy $bar = new two_refs 3,4,5,6; 853*0Sstevel@tonic-gate$bar->[2] = 11; 854*0Sstevel@tonic-gatetest $bar->{two}, 11; # 199 855*0Sstevel@tonic-gate$bar->{three} = 13; 856*0Sstevel@tonic-gatetest $bar->[3], 13; # 200 857*0Sstevel@tonic-gate 858*0Sstevel@tonic-gate{ 859*0Sstevel@tonic-gate package two_refs_o; 860*0Sstevel@tonic-gate @ISA = ('two_refs'); 861*0Sstevel@tonic-gate} 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate$bar = new two_refs_o 3,4,5,6; 864*0Sstevel@tonic-gate$bar->[2] = 11; 865*0Sstevel@tonic-gatetest $bar->{two}, 11; # 201 866*0Sstevel@tonic-gate$bar->{three} = 13; 867*0Sstevel@tonic-gatetest $bar->[3], 13; # 202 868*0Sstevel@tonic-gate 869*0Sstevel@tonic-gate{ 870*0Sstevel@tonic-gate package two_refs1; 871*0Sstevel@tonic-gate use overload '%{}' => sub { ${shift()}->[1] }, 872*0Sstevel@tonic-gate '@{}' => sub { ${shift()}->[0] }; 873*0Sstevel@tonic-gate sub new { 874*0Sstevel@tonic-gate my $p = shift; 875*0Sstevel@tonic-gate my $a = [@_]; 876*0Sstevel@tonic-gate my %h; 877*0Sstevel@tonic-gate tie %h, $p, $a; 878*0Sstevel@tonic-gate bless \ [$a, \%h], $p; 879*0Sstevel@tonic-gate } 880*0Sstevel@tonic-gate sub gethash { 881*0Sstevel@tonic-gate my %h; 882*0Sstevel@tonic-gate my $self = shift; 883*0Sstevel@tonic-gate tie %h, ref $self, $self; 884*0Sstevel@tonic-gate \%h; 885*0Sstevel@tonic-gate } 886*0Sstevel@tonic-gate 887*0Sstevel@tonic-gate sub TIEHASH { my $p = shift; bless \ shift, $p } 888*0Sstevel@tonic-gate my %fields; 889*0Sstevel@tonic-gate my $i = 0; 890*0Sstevel@tonic-gate $fields{$_} = $i++ foreach qw{zero one two three}; 891*0Sstevel@tonic-gate sub STORE { 892*0Sstevel@tonic-gate my $a = ${shift()}; 893*0Sstevel@tonic-gate my $key = $fields{shift()}; 894*0Sstevel@tonic-gate defined $key or die "Out of band access"; 895*0Sstevel@tonic-gate $a->[$key] = shift; 896*0Sstevel@tonic-gate } 897*0Sstevel@tonic-gate sub FETCH { 898*0Sstevel@tonic-gate my $a = ${shift()}; 899*0Sstevel@tonic-gate my $key = $fields{shift()}; 900*0Sstevel@tonic-gate defined $key or die "Out of band access"; 901*0Sstevel@tonic-gate $a->[$key]; 902*0Sstevel@tonic-gate } 903*0Sstevel@tonic-gate} 904*0Sstevel@tonic-gate 905*0Sstevel@tonic-gate$bar = new two_refs_o 3,4,5,6; 906*0Sstevel@tonic-gate$bar->[2] = 11; 907*0Sstevel@tonic-gatetest $bar->{two}, 11; # 203 908*0Sstevel@tonic-gate$bar->{three} = 13; 909*0Sstevel@tonic-gatetest $bar->[3], 13; # 204 910*0Sstevel@tonic-gate 911*0Sstevel@tonic-gate{ 912*0Sstevel@tonic-gate package two_refs1_o; 913*0Sstevel@tonic-gate @ISA = ('two_refs1'); 914*0Sstevel@tonic-gate} 915*0Sstevel@tonic-gate 916*0Sstevel@tonic-gate$bar = new two_refs1_o 3,4,5,6; 917*0Sstevel@tonic-gate$bar->[2] = 11; 918*0Sstevel@tonic-gatetest $bar->{two}, 11; # 205 919*0Sstevel@tonic-gate$bar->{three} = 13; 920*0Sstevel@tonic-gatetest $bar->[3], 13; # 206 921*0Sstevel@tonic-gate 922*0Sstevel@tonic-gate{ 923*0Sstevel@tonic-gate package B; 924*0Sstevel@tonic-gate use overload bool => sub { ${+shift} }; 925*0Sstevel@tonic-gate} 926*0Sstevel@tonic-gate 927*0Sstevel@tonic-gatemy $aaa; 928*0Sstevel@tonic-gate{ my $bbbb = 0; $aaa = bless \$bbbb, B } 929*0Sstevel@tonic-gate 930*0Sstevel@tonic-gatetest !$aaa, 1; # 207 931*0Sstevel@tonic-gate 932*0Sstevel@tonic-gateunless ($aaa) { 933*0Sstevel@tonic-gate test 'ok', 'ok'; # 208 934*0Sstevel@tonic-gate} else { 935*0Sstevel@tonic-gate test 'is not', 'ok'; # 208 936*0Sstevel@tonic-gate} 937*0Sstevel@tonic-gate 938*0Sstevel@tonic-gate# check that overload isn't done twice by join 939*0Sstevel@tonic-gate{ my $c = 0; 940*0Sstevel@tonic-gate package Join; 941*0Sstevel@tonic-gate use overload '""' => sub { $c++ }; 942*0Sstevel@tonic-gate my $x = join '', bless([]), 'pq', bless([]); 943*0Sstevel@tonic-gate main::test $x, '0pq1'; # 209 944*0Sstevel@tonic-gate}; 945*0Sstevel@tonic-gate 946*0Sstevel@tonic-gate# Test module-specific warning 947*0Sstevel@tonic-gate{ 948*0Sstevel@tonic-gate # check the Odd number of arguments for overload::constant warning 949*0Sstevel@tonic-gate my $a = "" ; 950*0Sstevel@tonic-gate local $SIG{__WARN__} = sub {$a = $_[0]} ; 951*0Sstevel@tonic-gate $x = eval ' overload::constant "integer" ; ' ; 952*0Sstevel@tonic-gate test($a eq "") ; # 210 953*0Sstevel@tonic-gate use warnings 'overload' ; 954*0Sstevel@tonic-gate $x = eval ' overload::constant "integer" ; ' ; 955*0Sstevel@tonic-gate test($a =~ /^Odd number of arguments for overload::constant at/) ; # 211 956*0Sstevel@tonic-gate} 957*0Sstevel@tonic-gate 958*0Sstevel@tonic-gate{ 959*0Sstevel@tonic-gate # check the `$_[0]' is not an overloadable type warning 960*0Sstevel@tonic-gate my $a = "" ; 961*0Sstevel@tonic-gate local $SIG{__WARN__} = sub {$a = $_[0]} ; 962*0Sstevel@tonic-gate $x = eval ' overload::constant "fred" => sub {} ; ' ; 963*0Sstevel@tonic-gate test($a eq "") ; # 212 964*0Sstevel@tonic-gate use warnings 'overload' ; 965*0Sstevel@tonic-gate $x = eval ' overload::constant "fred" => sub {} ; ' ; 966*0Sstevel@tonic-gate test($a =~ /^`fred' is not an overloadable type at/); # 213 967*0Sstevel@tonic-gate} 968*0Sstevel@tonic-gate 969*0Sstevel@tonic-gate{ 970*0Sstevel@tonic-gate # check the `$_[1]' is not a code reference warning 971*0Sstevel@tonic-gate my $a = "" ; 972*0Sstevel@tonic-gate local $SIG{__WARN__} = sub {$a = $_[0]} ; 973*0Sstevel@tonic-gate $x = eval ' overload::constant "integer" => 1; ' ; 974*0Sstevel@tonic-gate test($a eq "") ; # 214 975*0Sstevel@tonic-gate use warnings 'overload' ; 976*0Sstevel@tonic-gate $x = eval ' overload::constant "integer" => 1; ' ; 977*0Sstevel@tonic-gate test($a =~ /^`1' is not a code reference at/); # 215 978*0Sstevel@tonic-gate} 979*0Sstevel@tonic-gate 980*0Sstevel@tonic-gate{ 981*0Sstevel@tonic-gate my $c = 0; 982*0Sstevel@tonic-gate package ov_int1; 983*0Sstevel@tonic-gate use overload '""' => sub { 3+shift->[0] }, 984*0Sstevel@tonic-gate '0+' => sub { 10+shift->[0] }, 985*0Sstevel@tonic-gate 'int' => sub { 100+shift->[0] }; 986*0Sstevel@tonic-gate sub new {my $p = shift; bless [shift], $p} 987*0Sstevel@tonic-gate 988*0Sstevel@tonic-gate package ov_int2; 989*0Sstevel@tonic-gate use overload '""' => sub { 5+shift->[0] }, 990*0Sstevel@tonic-gate '0+' => sub { 30+shift->[0] }, 991*0Sstevel@tonic-gate 'int' => sub { 'ov_int1'->new(1000+shift->[0]) }; 992*0Sstevel@tonic-gate sub new {my $p = shift; bless [shift], $p} 993*0Sstevel@tonic-gate 994*0Sstevel@tonic-gate package noov_int; 995*0Sstevel@tonic-gate use overload '""' => sub { 2+shift->[0] }, 996*0Sstevel@tonic-gate '0+' => sub { 9+shift->[0] }; 997*0Sstevel@tonic-gate sub new {my $p = shift; bless [shift], $p} 998*0Sstevel@tonic-gate 999*0Sstevel@tonic-gate package main; 1000*0Sstevel@tonic-gate 1001*0Sstevel@tonic-gate my $x = new noov_int 11; 1002*0Sstevel@tonic-gate my $int_x = int $x; 1003*0Sstevel@tonic-gate main::test("$int_x" eq 20); # 216 1004*0Sstevel@tonic-gate $x = new ov_int1 31; 1005*0Sstevel@tonic-gate $int_x = int $x; 1006*0Sstevel@tonic-gate main::test("$int_x" eq 131); # 217 1007*0Sstevel@tonic-gate $x = new ov_int2 51; 1008*0Sstevel@tonic-gate $int_x = int $x; 1009*0Sstevel@tonic-gate main::test("$int_x" eq 1054); # 218 1010*0Sstevel@tonic-gate} 1011*0Sstevel@tonic-gate 1012*0Sstevel@tonic-gate# make sure that we don't inifinitely recurse 1013*0Sstevel@tonic-gate{ 1014*0Sstevel@tonic-gate my $c = 0; 1015*0Sstevel@tonic-gate package Recurse; 1016*0Sstevel@tonic-gate use overload '""' => sub { shift }, 1017*0Sstevel@tonic-gate '0+' => sub { shift }, 1018*0Sstevel@tonic-gate 'bool' => sub { shift }, 1019*0Sstevel@tonic-gate fallback => 1; 1020*0Sstevel@tonic-gate my $x = bless([]); 1021*0Sstevel@tonic-gate main::test("$x" =~ /Recurse=ARRAY/); # 219 1022*0Sstevel@tonic-gate main::test($x); # 220 1023*0Sstevel@tonic-gate main::test($x+0 =~ /Recurse=ARRAY/); # 221 1024*0Sstevel@tonic-gate} 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate# BugID 20010422.003 1027*0Sstevel@tonic-gatepackage Foo; 1028*0Sstevel@tonic-gate 1029*0Sstevel@tonic-gateuse overload 1030*0Sstevel@tonic-gate 'bool' => sub { return !$_[0]->is_zero() || undef; } 1031*0Sstevel@tonic-gate; 1032*0Sstevel@tonic-gate 1033*0Sstevel@tonic-gatesub is_zero 1034*0Sstevel@tonic-gate { 1035*0Sstevel@tonic-gate my $self = shift; 1036*0Sstevel@tonic-gate return $self->{var} == 0; 1037*0Sstevel@tonic-gate } 1038*0Sstevel@tonic-gate 1039*0Sstevel@tonic-gatesub new 1040*0Sstevel@tonic-gate { 1041*0Sstevel@tonic-gate my $class = shift; 1042*0Sstevel@tonic-gate my $self = {}; 1043*0Sstevel@tonic-gate $self->{var} = shift; 1044*0Sstevel@tonic-gate bless $self,$class; 1045*0Sstevel@tonic-gate } 1046*0Sstevel@tonic-gate 1047*0Sstevel@tonic-gatepackage main; 1048*0Sstevel@tonic-gate 1049*0Sstevel@tonic-gateuse strict; 1050*0Sstevel@tonic-gate 1051*0Sstevel@tonic-gatemy $r = Foo->new(8); 1052*0Sstevel@tonic-gate$r = Foo->new(0); 1053*0Sstevel@tonic-gate 1054*0Sstevel@tonic-gatetest(($r || 0) == 0); # 222 1055*0Sstevel@tonic-gate 1056*0Sstevel@tonic-gatepackage utf8_o; 1057*0Sstevel@tonic-gate 1058*0Sstevel@tonic-gateuse overload 1059*0Sstevel@tonic-gate '""' => sub { return $_[0]->{var}; } 1060*0Sstevel@tonic-gate ; 1061*0Sstevel@tonic-gate 1062*0Sstevel@tonic-gatesub new 1063*0Sstevel@tonic-gate { 1064*0Sstevel@tonic-gate my $class = shift; 1065*0Sstevel@tonic-gate my $self = {}; 1066*0Sstevel@tonic-gate $self->{var} = shift; 1067*0Sstevel@tonic-gate bless $self,$class; 1068*0Sstevel@tonic-gate } 1069*0Sstevel@tonic-gate 1070*0Sstevel@tonic-gatepackage main; 1071*0Sstevel@tonic-gate 1072*0Sstevel@tonic-gate 1073*0Sstevel@tonic-gatemy $utfvar = new utf8_o 200.2.1; 1074*0Sstevel@tonic-gatetest("$utfvar" eq 200.2.1); # 223 - stringify 1075*0Sstevel@tonic-gatetest("a$utfvar" eq "a".200.2.1); # 224 - overload via sv_2pv_flags 1076*0Sstevel@tonic-gate 1077*0Sstevel@tonic-gate# 225..227 -- more %{} tests. Hangs in 5.6.0, okay in later releases. 1078*0Sstevel@tonic-gate# Basically this example implements strong encapsulation: if Hderef::import() 1079*0Sstevel@tonic-gate# were to eval the overload code in the caller's namespace, the privatisation 1080*0Sstevel@tonic-gate# would be quite transparent. 1081*0Sstevel@tonic-gatepackage Hderef; 1082*0Sstevel@tonic-gateuse overload '%{}' => sub { (caller(0))[0] eq 'Foo' ? $_[0] : die "zap" }; 1083*0Sstevel@tonic-gatepackage Foo; 1084*0Sstevel@tonic-gate@Foo::ISA = 'Hderef'; 1085*0Sstevel@tonic-gatesub new { bless {}, shift } 1086*0Sstevel@tonic-gatesub xet { @_ == 2 ? $_[0]->{$_[1]} : 1087*0Sstevel@tonic-gate @_ == 3 ? ($_[0]->{$_[1]} = $_[2]) : undef } 1088*0Sstevel@tonic-gatepackage main; 1089*0Sstevel@tonic-gatemy $a = Foo->new; 1090*0Sstevel@tonic-gate$a->xet('b', 42); 1091*0Sstevel@tonic-gateprint $a->xet('b') == 42 ? "ok 225\n" : "not ok 225\n"; 1092*0Sstevel@tonic-gateprint defined eval { $a->{b} } ? "not ok 226\n" : "ok 226\n"; 1093*0Sstevel@tonic-gateprint $@ =~ /zap/ ? "ok 227\n" : "not ok 227\n"; 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gateprint overload::StrVal(qr/a/) =~ /^Regexp=SCALAR\(0x[0-9a-f]+\)$/ ? "ok 228\n" : "not ok 228\n"; 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate{ 1098*0Sstevel@tonic-gate package t229; 1099*0Sstevel@tonic-gate use overload '=' => sub { 42 }, 1100*0Sstevel@tonic-gate '++' => sub { my $x = ${$_[0]}; $_[0] }; 1101*0Sstevel@tonic-gate sub new { my $x = 42; bless \$x } 1102*0Sstevel@tonic-gate 1103*0Sstevel@tonic-gate my $warn; 1104*0Sstevel@tonic-gate { 1105*0Sstevel@tonic-gate local $SIG{__WARN__} = sub { $warn++ }; 1106*0Sstevel@tonic-gate my $x = t229->new; 1107*0Sstevel@tonic-gate my $y = $x; 1108*0Sstevel@tonic-gate eval { $y++ }; 1109*0Sstevel@tonic-gate } 1110*0Sstevel@tonic-gate print $warn ? "not ok 229\n" : "ok 229\n"; 1111*0Sstevel@tonic-gate} 1112*0Sstevel@tonic-gate 1113*0Sstevel@tonic-gate{ 1114*0Sstevel@tonic-gate package Numify; 1115*0Sstevel@tonic-gate use overload (qw(0+ numify fallback 1)); 1116*0Sstevel@tonic-gate 1117*0Sstevel@tonic-gate sub new { 1118*0Sstevel@tonic-gate my $val = $_[1]; 1119*0Sstevel@tonic-gate bless \$val, $_[0]; 1120*0Sstevel@tonic-gate } 1121*0Sstevel@tonic-gate 1122*0Sstevel@tonic-gate sub numify { ${$_[0]} } 1123*0Sstevel@tonic-gate} 1124*0Sstevel@tonic-gate 1125*0Sstevel@tonic-gate# These are all check that overloaded values rather than reference addressess 1126*0Sstevel@tonic-gate# are what is getting tested. 1127*0Sstevel@tonic-gatemy ($two, $one, $un, $deux) = map {new Numify $_} 2, 1, 1, 2; 1128*0Sstevel@tonic-gatemy ($ein, $zwei) = (1, 2); 1129*0Sstevel@tonic-gate 1130*0Sstevel@tonic-gatemy %map = (one => 1, un => 1, ein => 1, deux => 2, two => 2, zwei => 2); 1131*0Sstevel@tonic-gateforeach my $op (qw(<=> == != < <= > >=)) { 1132*0Sstevel@tonic-gate foreach my $l (keys %map) { 1133*0Sstevel@tonic-gate foreach my $r (keys %map) { 1134*0Sstevel@tonic-gate my $ocode = "\$$l $op \$$r"; 1135*0Sstevel@tonic-gate my $rcode = "$map{$l} $op $map{$r}"; 1136*0Sstevel@tonic-gate 1137*0Sstevel@tonic-gate my $got = eval $ocode; 1138*0Sstevel@tonic-gate die if $@; 1139*0Sstevel@tonic-gate my $expect = eval $rcode; 1140*0Sstevel@tonic-gate die if $@; 1141*0Sstevel@tonic-gate test ($got, $expect, $ocode) or print "# $rcode\n"; 1142*0Sstevel@tonic-gate } 1143*0Sstevel@tonic-gate } 1144*0Sstevel@tonic-gate} 1145*0Sstevel@tonic-gate 1146*0Sstevel@tonic-gate# Last test is: 1147*0Sstevel@tonic-gatesub last {476} 1148