1Test::Refcount(3) User Contributed Perl Documentation Test::Refcount(3)
2
3
4
6 "Test::Refcount" - assert reference counts on objects
7
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
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, a trace of references to the object can
36 be printed, if Marc Lehmann's Devel::FindRef module is installed. This
37 may assist the developer in finding where the references are. See the
38 examples below for more information.
39
41 is_refcount( $object, $count, $name )
42 Test that $object has $count references to it.
43
44 is_oneref( $object, $name )
45 Assert that the $object has only 1 reference to it.
46
48 Suppose, having written a new class "MyBall", you now want to check
49 that its constructor and methods are well-behaved, and don't leak
50 references. Consider the following test script:
51
52 use Test::More tests => 2;
53 use Test::Refcount;
54
55 use MyBall;
56
57 my $ball = MyBall->new();
58 is_oneref( $ball, 'One reference after construct' );
59
60 $ball->bounce;
61
62 # Any other code here that might be part of the test script
63
64 is_oneref( $ball, 'One reference just before EOF' );
65
66 The first assertion is just after the constructor, to check that the
67 reference returned by it is the only reference to that object. This
68 fact is important if we ever want "DESTROY" to behave properly. The
69 second call is right at the end of the file, just before the main scope
70 closes. At this stage we expect the reference count also to be one, so
71 that the object is properly cleaned up.
72
73 Suppose, when run, this produces the following output (presuming
74 "Devel::FindRef" is available):
75
76 1..2
77 ok 1 - One reference after construct
78 not ok 2 - One reference just before EOF
79 # Failed test 'One reference just before EOF'
80 # at demo.pl line 16.
81 # expected 1 references, found 2
82 # MyBall=ARRAY(0x817f880) is
83 # +- referenced by REF(0x82c1fd8), which is
84 # | in the member 'self' of HASH(0x82c1f68), which is
85 # | referenced by REF(0x81989d0), which is
86 # | in the member 'cycle' of HASH(0x82c1f68), which was seen before.
87 # +- referenced by REF(0x82811d0), which is
88 # in the lexical '$ball' in CODE(0x817fa00), which is
89 # the main body of the program.
90 # Looks like you failed 1 test of 2.
91
92 From this output, we can see that the constructor was well-behaved, but
93 that a reference was leaked by the end of the script - the reference
94 count was 2, when we expected just 1. Reading the trace output, we can
95 see that there were 2 references that "Devel::FindRef" could find - one
96 stored in the $ball lexical in the main program, and one stored in a
97 HASH. Since we expected to find the $ball lexical variable, we know we
98 are now looking for a leak in a hash somewhere in the code. From
99 reading the test script, we can guess this leak is likely to be in the
100 bounce() method. Furthermore, we know that the reference to the object
101 will be stored in a HASH in a member called "self".
102
103 By reading the code which implements the bounce() method, we can see
104 this is indeed the case:
105
106 sub bounce
107 {
108 my $self = shift;
109 my $cycle = { self => $self };
110 $cycle->{cycle} = $cycle;
111 }
112
113 From reading the "Devel::FindRef" output, we find that the HASH this
114 object is referenced in also contains a reference to itself, in a
115 member called "cycle". This comes from the last line in this function,
116 a line that purposely created a cycle, to demonstrate the point. While
117 a real program probably wouldn't do anything quite this obvious, the
118 trace would still be useful in finding the likely cause of the leak.
119
120 If "Devel::FindRef" is unavailable, then these detailed traces will not
121 be produced. The basic reference count testing will still take place,
122 but a smaller message will be produced:
123
124 1..2
125 ok 1 - One reference after construct
126 not ok 2 - One reference just before EOF
127 # Failed test 'One reference just before EOF'
128 # at demo.pl line 16.
129 # expected 1 references, found 2
130 # Looks like you failed 1 test of 2.
131
133 ยท Temporaries created on the stack
134
135 Code which creates temporaries on the stack, to be released again
136 when the called function returns does not work correctly on perl
137 5.8 (and probably before). Examples such as
138
139 is_oneref( [] );
140
141 may fail and claim a reference count of 2 instead.
142
143 Passing a variable such as
144
145 my $array = [];
146 is_oneref( $array );
147
148 works fine. Because of the intention of this test module; that is,
149 to assert reference counts on some object stored in a variable
150 during the lifetime of the test script, this is unlikely to cause
151 any problems.
152
154 Paul Evans <leonerd@leonerd.org.uk>
155
156
157
158perl v5.12.0 2009-11-24 Test::Refcount(3)