demonstrate that perl's GC is smarter than I am and that weakening in the get doesn...
[p5sagit/Mutually-Assured-Destruction.git] / notes / strong-and-weak.pl
CommitLineData
093a8e73 1#!/usr/bin/env perl
2
3use strict;
4use warnings;
5use Devel::GlobalDestruction ();
6use Scalar::Util ();
7use Variable::Magic ();
8use Carp ();
9
10BEGIN {
11 package Foo;
12
13 my $wiz;
14 $wiz = Variable::Magic::wizard
15 data => sub { $_[1] },
16 get => sub {
17 Carp::cluck "get fired";
18 Scalar::Util::weaken($_[1]->{reference}{other_side} = ${$_[0]});
19 Scalar::Util::weaken($_[1]->{reference});
20 Variable::Magic::dispell ${$_[0]}, $wiz;
21 };
22
23 sub DESTROY {
24 return if Devel::GlobalDestruction::in_global_destruction();
25 Carp::cluck "DESTROY\n";
26
27 my $self = shift;
28
29 if (ref $self->{other_side} && $self->{other_side}{reference}) {
30 if (
31 Scalar::Util::refaddr($self->{other_side}{reference})
32 eq Scalar::Util::refaddr($self)
33 ) {
34 warn "Enlivening";
35 $self->{other_side}{reference} = $self;
36 Variable::Magic::cast(
37 $self->{other_side}{reference}, $wiz, $self->{other_side}
38 );
39 delete $self->{other_side};
40 }
41 }
42 }
43}
44
45my $near = {};
46my $far = $near->{reference} = bless({ other_side => $near }, 'Foo');
47warn $near->{reference};
48warn $far;
49Scalar::Util::weaken($near->{reference});
50warn "Setup done\n";
51undef($far);
52my $copy = $near->{reference};
53warn $copy;
54warn Scalar::Util::isweak($near->{reference});
55warn $near->{reference};
56warn $near->{reference};
57undef($near);
58warn "Done\n";