1Test::Refcount(3)     User Contributed Perl Documentation    Test::Refcount(3)
2
3
4

NAME

6       "Test::Refcount" - assert reference counts on objects
7

SYNOPSIS

9        use Test::More tests => 2;
10        use Test::Refcount;
11
12        use Some::Class;
13
14        my $object = Some::Class->new();
15
16        is_oneref( $object, '$object has a refcount of 1' );
17
18        my $otherref = $object;
19
20        is_refcount( $object, 2, '$object now has 2 references' );
21

DESCRIPTION

23       The Perl garbage collector uses simple reference counting during the
24       normal execution of a program. This means that cycles or unweakened
25       references in other parts of code can keep an object around for longer
26       than intended. To help avoid this problem, the reference count of a new
27       object from its class constructor ought to be 1. This way, the caller
28       can know the object will be properly DESTROYed when it drops all of its
29       references to it.
30
31       This module provides two test functions to help ensure this property
32       holds for an object class, so as to be polite to its callers.
33
34       If the assertion fails; that is, if the actual reference count is
35       different to what was expected, either of the following two modules may
36       be used to assist the developer in finding where the references are.
37
38       ·   If Devel::FindRef module is installed, a reverse-references trace
39           is printed to the test output.
40
41       ·   If Devel::MAT is installed, this test module will use it to dump
42           the state of the memory after a failure. It will create a .pmat
43           file named the same as the unit test, but with the trailing .t
44           suffix replaced with -TEST.pmat where "TEST" is the number of the
45           test that failed (in case there was more than one).
46
47       See the examples below for more information.
48

FUNCTIONS

50   is_refcount( $object, $count, $name )
51       Test that $object has $count references to it.
52
53   is_oneref( $object, $name )
54       Assert that the $object has only 1 reference to it.
55

EXAMPLE

57       Suppose, having written a new class "MyBall", you now want to check
58       that its constructor and methods are well-behaved, and don't leak
59       references. Consider the following test script:
60
61        use Test::More tests => 2;
62        use Test::Refcount;
63
64        use MyBall;
65
66        my $ball = MyBall->new();
67        is_oneref( $ball, 'One reference after construct' );
68
69        $ball->bounce;
70
71        # Any other code here that might be part of the test script
72
73        is_oneref( $ball, 'One reference just before EOF' );
74
75       The first assertion is just after the constructor, to check that the
76       reference returned by it is the only reference to that object. This
77       fact is important if we ever want "DESTROY" to behave properly. The
78       second call is right at the end of the file, just before the main scope
79       closes. At this stage we expect the reference count also to be one, so
80       that the object is properly cleaned up.
81
82       Suppose, when run, this produces the following output (presuming
83       "Devel::FindRef" is available):
84
85        1..2
86        ok 1 - One reference after construct
87        not ok 2 - One reference just before EOF
88        #   Failed test 'One reference just before EOF'
89        #   at demo.pl line 16.
90        #   expected 1 references, found 2
91        # MyBall=ARRAY(0x817f880) is
92        # +- referenced by REF(0x82c1fd8), which is
93        # |     in the member 'self' of HASH(0x82c1f68), which is
94        # |        referenced by REF(0x81989d0), which is
95        # |           in the member 'cycle' of HASH(0x82c1f68), which was seen before.
96        # +- referenced by REF(0x82811d0), which is
97        #       in the lexical '$ball' in CODE(0x817fa00), which is
98        #          the main body of the program.
99        # Looks like you failed 1 test of 2.
100
101       From this output, we can see that the constructor was well-behaved, but
102       that a reference was leaked by the end of the script - the reference
103       count was 2, when we expected just 1. Reading the trace output, we can
104       see that there were 2 references that "Devel::FindRef" could find - one
105       stored in the $ball lexical in the main program, and one stored in a
106       HASH. Since we expected to find the $ball lexical variable, we know we
107       are now looking for a leak in a hash somewhere in the code. From
108       reading the test script, we can guess this leak is likely to be in the
109       bounce() method. Furthermore, we know that the reference to the object
110       will be stored in a HASH in a member called "self".
111
112       By reading the code which implements the bounce() method, we can see
113       this is indeed the case:
114
115        sub bounce
116        {
117           my $self = shift;
118           my $cycle = { self => $self };
119           $cycle->{cycle} = $cycle;
120        }
121
122       From reading the "Devel::FindRef" output, we find that the HASH this
123       object is referenced in also contains a reference to itself, in a
124       member called "cycle". This comes from the last line in this function,
125       a line that purposely created a cycle, to demonstrate the point. While
126       a real program probably wouldn't do anything quite this obvious, the
127       trace would still be useful in finding the likely cause of the leak.
128
129       If "Devel::FindRef" is unavailable, then these detailed traces will not
130       be produced. The basic reference count testing will still take place,
131       but a smaller message will be produced:
132
133        1..2
134        ok 1 - One reference after construct
135        not ok 2 - One reference just before EOF
136        #   Failed test 'One reference just before EOF'
137        #   at demo.pl line 16.
138        #   expected 1 references, found 2
139        # Looks like you failed 1 test of 2.
140

BUGS

142       ·   Temporaries created on the stack
143
144           Code which creates temporaries on the stack, to be released again
145           when the called function returns does not work correctly on perl
146           5.8 (and probably before). Examples such as
147
148            is_oneref( [] );
149
150           may fail and claim a reference count of 2 instead.
151
152           Passing a variable such as
153
154            my $array = [];
155            is_oneref( $array );
156
157           works fine. Because of the intention of this test module; that is,
158           to assert reference counts on some object stored in a variable
159           during the lifetime of the test script, this is unlikely to cause
160           any problems.
161

ACKNOWLEDGEMENTS

163       Peter Rabbitson <ribasushi@cpan.org> - for suggesting using core's "B"
164       instead of "Devel::Refcount" to obtain refcounts
165

AUTHOR

167       Paul Evans <leonerd@leonerd.org.uk>
168
169
170
171perl v5.28.0                      2014-03-27                 Test::Refcount(3)
Impressum