xref: /openbsd-src/gnu/usr.bin/perl/t/class/destruct.t (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
1f2a19305Safresh1#!./perl
2f2a19305Safresh1
3f2a19305Safresh1BEGIN {
4f2a19305Safresh1    chdir 't' if -d 't';
5f2a19305Safresh1    require './test.pl';
6f2a19305Safresh1    set_up_inc('../lib');
7f2a19305Safresh1    require Config;
8f2a19305Safresh1}
9f2a19305Safresh1
10f2a19305Safresh1use v5.36;
11f2a19305Safresh1use feature 'class';
12f2a19305Safresh1no warnings 'experimental::class';
13f2a19305Safresh1
14f2a19305Safresh1# A legacy-perl class to act as a test helper
15f2a19305Safresh1package DestructionNotify {
16f2a19305Safresh1    sub new { my $pkg = shift; bless [ @_ ], $pkg }
17f2a19305Safresh1    sub DESTROY { my $self = shift; ${ $self->[0] } .= $self->[1] }
18f2a19305Safresh1}
19f2a19305Safresh1
20f2a19305Safresh1{
21f2a19305Safresh1    my $destroyed;
22f2a19305Safresh1    my $notifier = DestructionNotify->new( \$destroyed, 1 );
23f2a19305Safresh1    undef $notifier;
24f2a19305Safresh1    $destroyed or
25f2a19305Safresh1        BAIL_OUT('DestructionNotify does not work');
26f2a19305Safresh1}
27f2a19305Safresh1
28f2a19305Safresh1{
29f2a19305Safresh1    my $destroyed;
30f2a19305Safresh1
31*5486feefSafresh1    class Testcase1 {
32f2a19305Safresh1        field $x;
33f2a19305Safresh1        method x { return $x; }
34f2a19305Safresh1        ADJUST {
35f2a19305Safresh1            $x = DestructionNotify->new( \$destroyed, "x" );
36f2a19305Safresh1        }
37f2a19305Safresh1
38f2a19305Safresh1        field $y;
39f2a19305Safresh1        field $z;
40f2a19305Safresh1        ADJUST {
41f2a19305Safresh1            # These in the "wrong" order just to prove to ourselves that it
42f2a19305Safresh1            # doesn't matter
43f2a19305Safresh1            $z = DestructionNotify->new( \$destroyed, "z" );
44f2a19305Safresh1            $y = DestructionNotify->new( \$destroyed, "y" );
45f2a19305Safresh1        }
46f2a19305Safresh1    }
47f2a19305Safresh1
48*5486feefSafresh1    my $obj = Testcase1->new;
49f2a19305Safresh1    ok(!$destroyed, 'Destruction notify not yet triggered');
50f2a19305Safresh1
51f2a19305Safresh1    refcount_is $obj, 1, 'Object has one reference';
52f2a19305Safresh1
53f2a19305Safresh1    # one in $obj, one stack temporary here
54f2a19305Safresh1    refcount_is $obj->x, 2, 'DestructionNotify has two references';
55f2a19305Safresh1
56f2a19305Safresh1    undef $obj;
57f2a19305Safresh1    is($destroyed, "zyx", 'Destruction notify triggered by object destruction in the correct order');
58f2a19305Safresh1}
59f2a19305Safresh1
60f2a19305Safresh1done_testing;
61