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

📄 overload.t

📁 UNIX下perl实现代码
💻 T
📖 第 1 页 / 共 2 页
字号:
    $#$obj = 1;     @$obj->[0,1] = ('=', shift);  }}{  my $foo = new symbolic 11;  my $baz = $foo++;  test( (sprintf "%d", $foo), '12');  test( (sprintf "%d", $baz), '11');  my $bar = $foo;  $baz = ++$foo;  test( (sprintf "%d", $foo), '13');  test( (sprintf "%d", $bar), '12');  test( (sprintf "%d", $baz), '13');  my $ban = $foo;  $baz = ($foo += 1);  test( (sprintf "%d", $foo), '14');  test( (sprintf "%d", $bar), '12');  test( (sprintf "%d", $baz), '14');  test( (sprintf "%d", $ban), '13');  $baz = 0;  $baz = $foo++;  test( (sprintf "%d", $foo), '15');  test( (sprintf "%d", $baz), '14');  test( "$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]');}{  my $iter = new symbolic 2;  my $side = new symbolic 1;  my $cnt = $iter;    while ($cnt) {    $cnt = $cnt - 1;		# The "simple" way    $side = (sqrt(1 + $side**2) - 1)/$side;  }  my $pi = $side*(2**($iter+2));  test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]';  test( (sprintf "%f", $pi), '3.182598');}{  my $iter = new symbolic 2;  my $side = new symbolic 1;  my $cnt = $iter;    while ($cnt--) {    $side = (sqrt(1 + $side**2) - 1)/$side;  }  my $pi = $side*(2**($iter+2));  test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]';  test( (sprintf "%f", $pi), '3.182598');}{  my ($a, $b);  symbolic->vars($a, $b);  my $c = sqrt($a**2 + $b**2);  $a = 3; $b = 4;  test( (sprintf "%d", $c), '5');  $a = 12; $b = 5;  test( (sprintf "%d", $c), '13');}{  package symbolic1;		# Primitive symbolic calculator  # Mutator inc/dec  use overload nomethod => \&wrap, '""' => \&str, '0+' => \&num, '=' => \&cpy;  sub new { shift; bless ['n', @_] }  sub cpy {    my $self = shift;    bless [@$self], ref $self;  }  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;     $#$obj = 1;     @$obj->[0,1] = ('=', shift);  }}{  my $foo = new symbolic1 11;  my $baz = $foo++;  test( (sprintf "%d", $foo), '12');  test( (sprintf "%d", $baz), '11');  my $bar = $foo;  $baz = ++$foo;  test( (sprintf "%d", $foo), '13');  test( (sprintf "%d", $bar), '12');  test( (sprintf "%d", $baz), '13');  my $ban = $foo;  $baz = ($foo += 1);  test( (sprintf "%d", $foo), '14');  test( (sprintf "%d", $bar), '12');  test( (sprintf "%d", $baz), '14');  test( (sprintf "%d", $ban), '13');  $baz = 0;  $baz = $foo++;  test( (sprintf "%d", $foo), '15');  test( (sprintf "%d", $baz), '14');  test( "$foo", '[++ [+= [++ [++ [n 11] 1] 1] 1] 1]');}{  my $iter = new symbolic1 2;  my $side = new symbolic1 1;  my $cnt = $iter;    while ($cnt) {    $cnt = $cnt - 1;		# The "simple" way    $side = (sqrt(1 + $side**2) - 1)/$side;  }  my $pi = $side*(2**($iter+2));  test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]';  test( (sprintf "%f", $pi), '3.182598');}{  my $iter = new symbolic1 2;  my $side = new symbolic1 1;  my $cnt = $iter;    while ($cnt--) {    $side = (sqrt(1 + $side**2) - 1)/$side;  }  my $pi = $side*(2**($iter+2));  test "$side", '[/ [- [sqrt [+ 1 [** [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]] 2]]] 1] [/ [- [sqrt [+ 1 [** [n 1] 2]]] 1] [n 1]]]';  test( (sprintf "%f", $pi), '3.182598');}{  my ($a, $b);  symbolic1->vars($a, $b);  my $c = sqrt($a**2 + $b**2);  $a = 3; $b = 4;  test( (sprintf "%d", $c), '5');  $a = 12; $b = 5;  test( (sprintf "%d", $c), '13');}{  package two_face;		# Scalars with separate string and                                # numeric values.  sub new { my $p = shift; bless [@_], $p }  use overload '""' => \&str, '0+' => \&num, fallback => 1;  sub num {shift->[1]}  sub str {shift->[0]}}{  my $seven = new two_face ("vii", 7);  test( (sprintf "seven=$seven, seven=%d, eight=%d", $seven, $seven+1),	'seven=vii, seven=7, eight=8');  test( scalar ($seven =~ /i/), '1')}{  package sorting;  use overload 'cmp' => \&comp;  sub new { my ($p, $v) = @_; bless \$v, $p }  sub comp { my ($x,$y) = @_; ($$x * 3 % 10) <=> ($$y * 3 % 10) or $$x cmp $$y }}{  my @arr = map sorting->new($_), 0..12;  my @sorted1 = sort @arr;  my @sorted2 = map $$_, @sorted1;  test "@sorted2", '0 10 7 4 1 11 8 5 12 2 9 6 3';}{  package iterator;  use overload '<>' => \&iter;  sub new { my ($p, $v) = @_; bless \$v, $p }  sub iter { my ($x) = @_; return undef if $$x < 0; return $$x--; }}# XXX iterator overload not intended to work with CORE::GLOBAL?if (defined &CORE::GLOBAL::glob) {  test '1', '1';	# 175  test '1', '1';	# 176  test '1', '1';	# 177}else {  my $iter = iterator->new(5);  my $acc = '';  my $out;  $acc .= " $out" while $out = <${iter}>;  test $acc, ' 5 4 3 2 1 0';	# 175  $iter = iterator->new(5);  test scalar <${iter}>, '5';	# 176  $acc = '';  $acc .= " $out" while $out = <$iter>;  test $acc, ' 4 3 2 1 0';	# 177}{  package deref;  use overload '%{}' => \&hderef, '&{}' => \&cderef,     '*{}' => \&gderef, '${}' => \&sderef, '@{}' => \&aderef;  sub new { my ($p, $v) = @_; bless \$v, $p }  sub deref {    my ($self, $key) = (shift, shift);    my $class = ref $self;    bless $self, 'deref::dummy'; # Disable overloading of %{}     my $out = $self->{$key};    bless $self, $class;	# Restore overloading    $out;  }  sub hderef {shift->deref('h')}  sub aderef {shift->deref('a')}  sub cderef {shift->deref('c')}  sub gderef {shift->deref('g')}  sub sderef {shift->deref('s')}}{  my $deref = bless { h => { foo => 5 , fake => 23 },		      c => sub {return shift() + 34},		      's' => \123,		      a => [11..13],		      g => \*srt,		    }, 'deref';  # Hash:  my @cont = sort %$deref;  if ("\t" eq "\011") { # ascii      test "@cont", '23 5 fake foo';	# 178  }   else {                # ebcdic alpha-numeric sort order      test "@cont", 'fake foo 23 5';	# 178  }  my @keys = sort keys %$deref;  test "@keys", 'fake foo';	# 179  my @val = sort values %$deref;  test "@val", '23 5';		# 180  test $deref->{foo}, 5;	# 181  test defined $deref->{bar}, ''; # 182  my $key;  @keys = ();  push @keys, $key while $key = each %$deref;  @keys = sort @keys;  test "@keys", 'fake foo';	# 183    test exists $deref->{bar}, ''; # 184  test exists $deref->{foo}, 1; # 185  # Code:  test $deref->(5), 39;		# 186  test &$deref(6), 40;		# 187  sub xxx_goto { goto &$deref }  test xxx_goto(7), 41;		# 188  my $srt = bless { c => sub {$b <=> $a}		  }, 'deref';  *srt = \&$srt;  my @sorted = sort srt 11, 2, 5, 1, 22;  test "@sorted", '22 11 5 2 1'; # 189  # Scalar  test $$deref, 123;		# 190  # Code  @sorted = sort $srt 11, 2, 5, 1, 22;  test "@sorted", '22 11 5 2 1'; # 191  # Array  test "@$deref", '11 12 13';	# 192  test $#$deref, '2';		# 193  my $l = @$deref;  test $l, 3;			# 194  test $deref->[2], '13';		# 195  $l = pop @$deref;  test $l, 13;			# 196  $l = 1;  test $deref->[$l], '12';	# 197  # Repeated dereference  my $double = bless { h => $deref,		     }, 'deref';  test $double->{foo}, 5;	# 198}{  package two_refs;  use overload '%{}' => \&gethash, '@{}' => sub { ${shift()} };  sub new {     my $p = shift;     bless \ [@_], $p;  }  sub gethash {    my %h;    my $self = shift;    tie %h, ref $self, $self;    \%h;  }  sub TIEHASH { my $p = shift; bless \ shift, $p }  my %fields;  my $i = 0;  $fields{$_} = $i++ foreach qw{zero one two three};  sub STORE {     my $self = ${shift()};    my $key = $fields{shift()};    defined $key or die "Out of band access";    $$self->[$key] = shift;  }  sub FETCH {     my $self = ${shift()};    my $key = $fields{shift()};    defined $key or die "Out of band access";    $$self->[$key];  }}my $bar = new two_refs 3,4,5,6;$bar->[2] = 11;test $bar->{two}, 11;		# 199$bar->{three} = 13;test $bar->[3], 13;		# 200{  package two_refs_o;  @ISA = ('two_refs');}$bar = new two_refs_o 3,4,5,6;$bar->[2] = 11;test $bar->{two}, 11;		# 201$bar->{three} = 13;test $bar->[3], 13;		# 202{  package two_refs1;  use overload '%{}' => sub { ${shift()}->[1] },               '@{}' => sub { ${shift()}->[0] };  sub new {     my $p = shift;     my $a = [@_];    my %h;    tie %h, $p, $a;    bless \ [$a, \%h], $p;  }  sub gethash {    my %h;    my $self = shift;    tie %h, ref $self, $self;    \%h;  }  sub TIEHASH { my $p = shift; bless \ shift, $p }  my %fields;  my $i = 0;  $fields{$_} = $i++ foreach qw{zero one two three};  sub STORE {     my $a = ${shift()};    my $key = $fields{shift()};    defined $key or die "Out of band access";    $a->[$key] = shift;  }  sub FETCH {     my $a = ${shift()};    my $key = $fields{shift()};    defined $key or die "Out of band access";    $a->[$key];  }}$bar = new two_refs_o 3,4,5,6;$bar->[2] = 11;test $bar->{two}, 11;		# 203$bar->{three} = 13;test $bar->[3], 13;		# 204{  package two_refs1_o;  @ISA = ('two_refs1');}$bar = new two_refs1_o 3,4,5,6;$bar->[2] = 11;test $bar->{two}, 11;		# 205$bar->{three} = 13;test $bar->[3], 13;		# 206{  package B;  use overload bool => sub { ${+shift} };}my $aaa;{ my $bbbb = 0; $aaa = bless \$bbbb, B }test !$aaa, 1;			# 207unless ($aaa) {  test 'ok', 'ok';		# 208} else {  test 'is not', 'ok';		# 208}# check that overload isn't done twice by join{ my $c = 0;  package Join;  use overload '""' => sub { $c++ };  my $x = join '', bless([]), 'pq', bless([]);  main::test $x, '0pq1';		# 209};# Test module-specific warning{    # check the Odd number of arguments for overload::constant warning    my $a = "" ;    local $SIG{__WARN__} = sub {$a = $_[0]} ;    $x = eval ' overload::constant "integer" ; ' ;    test($a eq "") ; # 210    use warnings 'overload' ;    $x = eval ' overload::constant "integer" ; ' ;    test($a =~ /^Odd number of arguments for overload::constant at/) ; # 211}{    # check the `$_[0]' is not an overloadable type warning    my $a = "" ;    local $SIG{__WARN__} = sub {$a = $_[0]} ;    $x = eval ' overload::constant "fred" => sub {} ; ' ;    test($a eq "") ; # 212    use warnings 'overload' ;    $x = eval ' overload::constant "fred" => sub {} ; ' ;    test($a =~ /^`fred' is not an overloadable type at/); # 213}{    # check the `$_[1]' is not a code reference warning    my $a = "" ;    local $SIG{__WARN__} = sub {$a = $_[0]} ;    $x = eval ' overload::constant "integer" => 1; ' ;    test($a eq "") ; # 214    use warnings 'overload' ;    $x = eval ' overload::constant "integer" => 1; ' ;    test($a =~ /^`1' is not a code reference at/); # 215}# make sure that we don't inifinitely recurse{  my $c = 0;  package Recurse;  use overload '""'    => sub { shift },               '0+'    => sub { shift },               'bool'  => sub { shift },               fallback => 1;  my $x = bless([]);  main::test("$x" =~ /Recurse=ARRAY/);		# 216  main::test($x);                               # 217  main::test($x+0 =~ /Recurse=ARRAY/);		# 218};# Last test is:sub last {218}

⌨️ 快捷键说明

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