Update to Scalar-List-Utils-1.15
[p5sagit/p5-mst-13.2.git] / ext / List / Util / t / weak.t
CommitLineData
1bfb5477 1#!./perl
2
f4a2945e 3BEGIN {
1bfb5477 4 unless (-d 'blib') {
f4a2945e 5 chdir 't' if -d 't';
6 @INC = '../lib';
6b05f64e 7 require Config; import Config;
1bfb5477 8 keys %Config; # Silence warning
6b05f64e 9 if ($Config{extensions} !~ /\bList\/Util\b/) {
10 print "1..0 # Skip: List::Util was not built\n";
11 exit 0;
12 }
1bfb5477 13 }
f4a2945e 14}
15
cf083cf9 16use Scalar::Util ();
17use Test::More (grep { /weaken/ } @Scalar::Util::EXPORT_FAIL)
18 ? (skip_all => 'weaken requires XS version')
19 : (tests => 22);
20
21if (0) {
22 require Devel::Peek;
23 Devel::Peek->import('Dump');
f4a2945e 24}
cf083cf9 25else {
26 *Dump = sub {};
f4a2945e 27}
28
cf083cf9 29Scalar::Util->import(qw(weaken isweak));
f4a2945e 30
31if(1) {
32
33my ($y,$z);
34
35#
36# Case 1: two references, one is weakened, the other is then undef'ed.
37#
38
39{
40 my $x = "foo";
41 $y = \$x;
42 $z = \$x;
43}
cf083cf9 44print "# START\n";
f4a2945e 45Dump($y); Dump($z);
46
cf083cf9 47ok( ref($y) and ref($z));
f4a2945e 48
49print "# WEAK:\n";
cf083cf9 50weaken($y);
f4a2945e 51Dump($y); Dump($z);
52
cf083cf9 53ok( ref($y) and ref($z));
f4a2945e 54
55print "# UNDZ:\n";
cf083cf9 56undef($z);
f4a2945e 57Dump($y); Dump($z);
58
59ok( not (defined($y) and defined($z)) );
f4a2945e 60
61print "# UNDY:\n";
cf083cf9 62undef($y);
f4a2945e 63Dump($y); Dump($z);
64
65ok( not (defined($y) and defined($z)) );
66
67print "# FIN:\n";
68Dump($y); Dump($z);
69
f4a2945e 70
71#
72# Case 2: one reference, which is weakened
73#
74
f4a2945e 75print "# CASE 2:\n";
76
77{
78 my $x = "foo";
79 $y = \$x;
80}
81
cf083cf9 82ok( ref($y) );
f4a2945e 83print "# BW: \n";
84Dump($y);
85weaken($y);
86print "# AW: \n";
87Dump($y);
88ok( not defined $y );
89
90print "# EXITBLOCK\n";
91}
92
f4a2945e 93#
94# Case 3: a circular structure
95#
96
f4a2945e 97$flag = 0;
98{
99 my $y = bless {}, Dest;
100 Dump($y);
101 print "# 1: $y\n";
102 $y->{Self} = $y;
103 Dump($y);
104 print "# 2: $y\n";
105 $y->{Flag} = \$flag;
106 print "# 3: $y\n";
107 weaken($y->{Self});
108 print "# WKED\n";
cf083cf9 109 ok( ref($y) );
f4a2945e 110 print "# VALS: HASH ",$y," SELF ",\$y->{Self}," Y ",\$y,
111 " FLAG: ",\$y->{Flag},"\n";
112 print "# VPRINT\n";
113}
114print "# OUT $flag\n";
115ok( $flag == 1 );
116
117print "# AFTER\n";
118
119undef $flag;
120
121print "# FLAGU\n";
122
123#
124# Case 4: a more complicated circular structure
125#
126
127$flag = 0;
128{
129 my $y = bless {}, Dest;
130 my $x = bless {}, Dest;
131 $x->{Ref} = $y;
132 $y->{Ref} = $x;
133 $x->{Flag} = \$flag;
134 $y->{Flag} = \$flag;
135 weaken($x->{Ref});
136}
137ok( $flag == 2 );
138
139#
140# Case 5: deleting a weakref before the other one
141#
142
143{
144 my $x = "foo";
145 $y = \$x;
146 $z = \$x;
147}
148
149print "# CASE5\n";
150Dump($y);
151
152weaken($y);
153Dump($y);
154undef($y);
155
156ok( not defined $y);
cf083cf9 157ok( ref($z) );
f4a2945e 158
159
160#
161# Case 6: test isweakref
162#
163
164$a = 5;
165ok(!isweak($a));
166$b = \$a;
167ok(!isweak($b));
168weaken($b);
169ok(isweak($b));
170$b = \$a;
171ok(!isweak($b));
172
173$x = {};
174weaken($x->{Y} = \$a);
175ok(isweak($x->{Y}));
176ok(!isweak($x->{Z}));
177
e6469971 178#
179# Case 7: test weaken on a read only ref
180#
181
cf083cf9 182SKIP: {
e6469971 183 # Doesn't work for older perls, see bug [perl #24506]
cf083cf9 184 skip("Test does not work with perl < 5.8.3", 5) if $] < 5.008003;
185
e6469971 186 $a = eval '\"hello"';
187 ok(ref($a)) or print "# didn't get a ref from eval\n";
188 $b = $a;
189 eval{weaken($b)};
190 # we didn't die
191 ok($@ eq "") or print "# died with $@\n";
192 ok(isweak($b));
193 ok($$b eq "hello") or print "# b is '$$b'\n";
194 $a="";
195 ok(not $b) or print "# b didn't go away\n";
196}
f4a2945e 197
198package Dest;
199
200sub DESTROY {
201 print "# INCFLAG\n";
202 ${$_[0]{Flag}} ++;
203}