⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overload.t

📁 UNIX下perl实现代码
💻 T
📖 第 1 页 / 共 2 页
字号:
#!./perlBEGIN {    chdir 't' if -d 't';    @INC = '../lib';}package Oscalar;use overload ( 				# Anonymous subroutines:'+'	=>	sub {new Oscalar $ {$_[0]}+$_[1]},'-'	=>	sub {new Oscalar		       $_[2]? $_[1]-${$_[0]} : ${$_[0]}-$_[1]},'<=>'	=>	sub {new Oscalar		       $_[2]? $_[1]-${$_[0]} : ${$_[0]}-$_[1]},'cmp'	=>	sub {new Oscalar		       $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},'*'	=>	sub {new Oscalar ${$_[0]}*$_[1]},'/'	=>	sub {new Oscalar 		       $_[2]? $_[1]/${$_[0]} :			 ${$_[0]}/$_[1]},'%'	=>	sub {new Oscalar		       $_[2]? $_[1]%${$_[0]} : ${$_[0]}%$_[1]},'**'	=>	sub {new Oscalar		       $_[2]? $_[1]**${$_[0]} : ${$_[0]}-$_[1]},qw(""	stringify0+	numify)			# Order of arguments unsignificant);sub new {  my $foo = $_[1];  bless \$foo, $_[0];}sub stringify { "${$_[0]}" }sub numify { 0 + "${$_[0]}" }	# Not needed, additional overhead				# comparing to direct compilation based on				# stringifypackage main;$test = 0;$| = 1;print "1..",&last,"\n";sub test {  $test++;   if (@_ > 1) {    if ($_[0] eq $_[1]) {      print "ok $test\n";    } else {      print "not ok $test: '$_[0]' ne '$_[1]'\n";    }  } else {    if (shift) {      print "ok $test\n";    } else {      print "not ok $test\n";    }   }}$a = new Oscalar "087";$b= "$a";# All test numbers in comments are off by 1.# So much for hard-wiring them in :-) To fix this:test(1);			# 1test ($b eq $a);		# 2test ($b eq "087");		# 3test (ref $a eq "Oscalar");	# 4test ($a eq $a);		# 5test ($a eq "087");		# 6$c = $a + 7;test (ref $c eq "Oscalar");	# 7test (!($c eq $a));		# 8test ($c eq "94");		# 9$b=$a;test (ref $a eq "Oscalar");	# 10$b++;test (ref $b eq "Oscalar");	# 11test ( $a eq "087");		# 12test ( $b eq "88");		# 13test (ref $a eq "Oscalar");	# 14$c=$b;$c-=$a;test (ref $c eq "Oscalar");	# 15test ( $a eq "087");		# 16test ( $c eq "1");		# 17test (ref $a eq "Oscalar");	# 18$b=1;$b+=$a;test (ref $b eq "Oscalar");	# 19test ( $a eq "087");		# 20test ( $b eq "88");		# 21test (ref $a eq "Oscalar");	# 22eval q[ package Oscalar; use overload ('++' => sub { $ {$_[0]}++;$_[0] } ) ];$b=$a;test (ref $a eq "Oscalar");	# 23$b++;test (ref $b eq "Oscalar");	# 24test ( $a eq "087");		# 25test ( $b eq "88");		# 26test (ref $a eq "Oscalar");	# 27package Oscalar;$dummy=bless \$dummy;		# Now cache of method should be reloadedpackage main;$b=$a;$b++;				test (ref $b eq "Oscalar");	# 28test ( $a eq "087");		# 29test ( $b eq "88");		# 30test (ref $a eq "Oscalar");	# 31eval q[package Oscalar; use overload ('++' => sub { $ {$_[0]} += 2; $_[0] } ) ];$b=$a;test (ref $a eq "Oscalar");	# 32$b++;test (ref $b eq "Oscalar");	# 33test ( $a eq "087");		# 34test ( $b eq "88");		# 35test (ref $a eq "Oscalar");	# 36package Oscalar;$dummy=bless \$dummy;		# Now cache of method should be reloadedpackage main;$b++;				test (ref $b eq "Oscalar");	# 37test ( $a eq "087");		# 38test ( $b eq "90");		# 39test (ref $a eq "Oscalar");	# 40$b=$a;$b++;test (ref $b eq "Oscalar");	# 41test ( $a eq "087");		# 42test ( $b eq "89");		# 43test (ref $a eq "Oscalar");	# 44test ($b? 1:0);			# 45eval q[ package Oscalar; use overload ('=' => sub {$main::copies++; 						   package Oscalar;						   local $new=$ {$_[0]};						   bless \$new } ) ];$b=new Oscalar "$a";test (ref $b eq "Oscalar");	# 46test ( $a eq "087");		# 47test ( $b eq "087");		# 48test (ref $a eq "Oscalar");	# 49$b++;test (ref $b eq "Oscalar");	# 50test ( $a eq "087");		# 51test ( $b eq "89");		# 52test (ref $a eq "Oscalar");	# 53test ($copies == 0);		# 54$b+=1;test (ref $b eq "Oscalar");	# 55test ( $a eq "087");		# 56test ( $b eq "90");		# 57test (ref $a eq "Oscalar");	# 58test ($copies == 0);		# 59$b=$a;$b+=1;test (ref $b eq "Oscalar");	# 60test ( $a eq "087");		# 61test ( $b eq "88");		# 62test (ref $a eq "Oscalar");	# 63test ($copies == 0);		# 64$b=$a;$b++;test (ref $b eq "Oscalar") || print ref $b,"=ref(b)\n";	# 65test ( $a eq "087");		# 66test ( $b eq "89");		# 67test (ref $a eq "Oscalar");	# 68test ($copies == 1);		# 69eval q[package Oscalar; use overload ('+=' => sub {$ {$_[0]} += 3*$_[1];						   $_[0] } ) ];$c=new Oscalar;			# Cause rehash$b=$a;$b+=1;test (ref $b eq "Oscalar");	# 70test ( $a eq "087");		# 71test ( $b eq "90");		# 72test (ref $a eq "Oscalar");	# 73test ($copies == 2);		# 74$b+=$b;test (ref $b eq "Oscalar");	# 75test ( $b eq "360");		# 76test ($copies == 2);		# 77$b=-$b;test (ref $b eq "Oscalar");	# 78test ( $b eq "-360");		# 79test ($copies == 2);		# 80$b=abs($b);test (ref $b eq "Oscalar");	# 81test ( $b eq "360");		# 82test ($copies == 2);		# 83$b=abs($b);test (ref $b eq "Oscalar");	# 84test ( $b eq "360");		# 85test ($copies == 2);		# 86eval q[package Oscalar;        use overload ('x' => sub {new Oscalar ( $_[2] ? "_.$_[1]._" x $ {$_[0]}					      : "_.${$_[0]}._" x $_[1])}) ];$a=new Oscalar "yy";$a x= 3;test ($a eq "_.yy.__.yy.__.yy._"); # 87eval q[package Oscalar;        use overload ('.' => sub {new Oscalar ( $_[2] ? 					      "_.$_[1].__.$ {$_[0]}._"					      : "_.$ {$_[0]}.__.$_[1]._")}) ];$a=new Oscalar "xx";test ("b${a}c" eq "_._.b.__.xx._.__.c._"); # 88# Check inheritance of overloading;{  package OscalarI;  @ISA = 'Oscalar';}$aI = new OscalarI "$a";test (ref $aI eq "OscalarI");	# 89test ("$aI" eq "xx");		# 90test ($aI eq "xx");		# 91test ("b${aI}c" eq "_._.b.__.xx._.__.c._");		# 92# Here we test blessing to a package updates hasheval "package Oscalar; no overload '.'";test ("b${a}" eq "_.b.__.xx._"); # 93$x="1";bless \$x, Oscalar;test ("b${a}c" eq "bxxc");	# 94new Oscalar 1;test ("b${a}c" eq "bxxc");	# 95# Negative overloading:$na = eval { ~$a };test($@ =~ /no method found/);	# 96# Check AUTOLOADING:*Oscalar::AUTOLOAD =   sub { *{"Oscalar::$AUTOLOAD"} = sub {"_!_" . shift() . "_!_"} ;	goto &{"Oscalar::$AUTOLOAD"}};eval "package Oscalar; sub comple; use overload '~' => 'comple'";$na = eval { ~$a };		# Hash was not updatedtest($@ =~ /no method found/);	# 97bless \$x, Oscalar;$na = eval { ~$a };		# Hash updatedwarn "`$na', $@" if $@;test !$@;			# 98test($na eq '_!_xx_!_');	# 99$na = 0;$na = eval { ~$aI };		# Hash was not updatedtest($@ =~ /no method found/);	# 100bless \$x, OscalarI;$na = eval { ~$aI };print $@;test !$@;			# 101test($na eq '_!_xx_!_');	# 102eval "package Oscalar; sub rshft; use overload '>>' => 'rshft'";$na = eval { $aI >> 1 };	# Hash was not updatedtest($@ =~ /no method found/);	# 103bless \$x, OscalarI;$na = 0;$na = eval { $aI >> 1 };print $@;test !$@;			# 104test($na eq '_!_xx_!_');	# 105# warn overload::Method($a, '0+'), "\n";test (overload::Method($a, '0+') eq \&Oscalar::numify); # 106test (overload::Method($aI,'0+') eq \&Oscalar::numify); # 107test (overload::Overloaded($aI)); # 108test (!overload::Overloaded('overload')); # 109test (! defined overload::Method($aI, '<<')); # 110test (! defined overload::Method($a, '<')); # 111test (overload::StrVal($aI) =~ /^OscalarI=SCALAR\(0x[\da-fA-F]+\)$/); # 112test (overload::StrVal(\$aI) eq "@{[\$aI]}"); # 113# Check overloading by methods (specified deep in the ISA tree).{  package OscalarII;  @ISA = 'OscalarI';  sub Oscalar::lshft {"_<<_" . shift() . "_<<_"}  eval "package OscalarI; use overload '<<' => 'lshft', '|' => 'lshft'";}$aaII = "087";$aII = \$aaII;bless $aII, 'OscalarII';bless \$fake, 'OscalarI';		# update the hashtest(($aI | 3) eq '_<<_xx_<<_');	# 114# warn $aII << 3;test(($aII << 3) eq '_<<_087_<<_');	# 115{  BEGIN { $int = 7; overload::constant 'integer' => sub {$int++; shift}; }  $out = 2**10;}test($int, 9);		# 116test($out, 1024);		# 117$foo = 'foo';$foo1 = 'f\'o\\o';{  BEGIN { $q = $qr = 7; 	  overload::constant 'q' => sub {$q++; push @q, shift, ($_[1] || 'none'); shift},			     'qr' => sub {$qr++; push @qr, shift, ($_[1] || 'none'); shift}; }  $out = 'foo';  $out1 = 'f\'o\\o';  $out2 = "a\a$foo,\,";  /b\b$foo.\./;}test($out, 'foo');		# 118test($out, $foo);		# 119test($out1, 'f\'o\\o');		# 120test($out1, $foo1);		# 121test($out2, "a\afoo,\,");	# 122test("@q", "foo q f'o\\\\o q a\\a qq ,\\, qq");	# 123test($q, 11);			# 124test("@qr", "b\\b qq .\\. qq");	# 125test($qr, 9);			# 126{  $_ = '!<b>!foo!<-.>!';  BEGIN { overload::constant 'q' => sub {push @q1, shift, ($_[1] || 'none'); "_<" . (shift) . ">_"},			     'qr' => sub {push @qr1, shift, ($_[1] || 'none'); "!<" . (shift) . ">!"}; }  $out = 'foo';  $out1 = 'f\'o\\o';  $out2 = "a\a$foo,\,";  $res = /b\b$foo.\./;  $a = <<EOF;oupsEOF  $b = <<'EOF';oups1EOF  $c = bareword;  m'try it';  s'first part'second part';  s/yet another/tail here/;  tr/z-Z/z-Z/;}test($out, '_<foo>_');		# 117test($out1, '_<f\'o\\o>_');		# 128test($out2, "_<a\a>_foo_<,\,>_");	# 129test("@q1", "foo q f'o\\\\o q a\\a qq ,\\, qq oups qq oups1 q second part q tail here s z-Z tr z-Z tr");	# 130test("@qr1", "b\\b qq .\\. qq try it q first part q yet another qq");	# 131test($res, 1);			# 132test($a, "_<oups>_");	# 133test($b, "_<oups1>_");	# 134test($c, "bareword");	# 135{  package symbolic;		# Primitive symbolic calculator  use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num,      '=' => \&cpy, '++' => \&inc, '--' => \&dec;  sub new { shift; bless ['n', @_] }  sub cpy {    my $self = shift;    bless [@$self], ref $self;  }  sub inc { $_[0] = bless ['++', $_[0], 1]; }  sub dec { $_[0] = bless ['--', $_[0], 1]; }  sub wrap {    my ($obj, $other, $inv, $meth) = @_;    if ($meth eq '++' or $meth eq '--') {      @$obj = ($meth, (bless [@$obj]), 1); # Avoid circular reference      return $obj;    }    ($obj, $other) = ($other, $obj) if $inv;    bless [$meth, $obj, $other];  }  sub str {    my ($meth, $a, $b) = @{+shift};    $a = 'u' unless defined $a;    if (defined $b) {      "[$meth $a $b]";    } else {      "[$meth $a]";    }  }   my %subr = ( 'n' => sub {$_[0]} );  foreach my $op (split " ", $overload::ops{with_assign}) {    $subr{$op} = $subr{"$op="} = eval "sub {shift() $op shift()}";  }  my @bins = qw(binary 3way_comparison num_comparison str_comparison);  foreach my $op (split " ", "@overload::ops{ @bins }") {    $subr{$op} = eval "sub {shift() $op shift()}";  }  foreach my $op (split " ", "@overload::ops{qw(unary func)}") {    $subr{$op} = eval "sub {$op shift()}";  }  $subr{'++'} = $subr{'+'};  $subr{'--'} = $subr{'-'};    sub num {    my ($meth, $a, $b) = @{+shift};    my $subr = $subr{$meth}       or die "Do not know how to ($meth) in symbolic";    $a = $a->num if ref $a eq __PACKAGE__;    $b = $b->num if ref $b eq __PACKAGE__;    $subr->($a,$b);  }  sub TIESCALAR { my $pack = shift; $pack->new(@_) }  sub FETCH { shift }  sub nop {  }		# Around a bug  sub vars { my $p = shift; tie($_, $p), $_->nop foreach @_; }  sub STORE {     my $obj = shift; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -