show single firing wizard for get
[p5sagit/Mutually-Assured-Destruction.git] / notes / strong-with-getonce.pl
1 #!/usr/bin/env perl
2
3 use strict;
4 use warnings;
5 use Devel::GlobalDestruction ();
6 use Scalar::Util ();
7 use Variable::Magic ();
8 use Carp ();
9
10 BEGIN {
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       Variable::Magic::dispell ${$_[0]}, $wiz;
19     };
20
21   sub DESTROY {
22     return if Devel::GlobalDestruction::in_global_destruction();
23     warn "DESTROY\n";
24
25     my $self = shift;
26
27     if (ref $self->{other_side} && $self->{other_side}{reference}) {
28       if (
29         Scalar::Util::refaddr($self->{other_side}{reference})
30         eq Scalar::Util::refaddr($self)
31       ) {
32         warn "Enlivening";
33         $self->{other_side}{reference} = $self;
34         Variable::Magic::cast $self->{other_side}{reference}, $wiz;
35         delete $self->{other_side};
36       }
37     }
38   }
39 }
40
41 my $near = {};
42 my $far = $near->{reference} = bless({ other_side => $near }, 'Foo');
43 warn $near->{reference};
44 warn $far;
45 Scalar::Util::weaken($near->{reference});
46 warn "Setup done\n";
47 undef($far);
48 warn $near->{reference};
49 warn $near->{reference};
50 Scalar::Util::weaken($near->{reference});
51 warn $near->{reference};