1Sub::Override(3) User Contributed Perl Documentation Sub::Override(3)
2
3
4
6 Sub::Override - Perl extension for easily overriding subroutines
7
9 use Sub::Override;
10
11 sub foo { 'original sub' };
12 print foo(); # prints 'original sub'
13
14 my $override = Sub::Override->new( foo => sub { 'overridden sub' } );
15 print foo(); # prints 'overridden sub'
16 $override->restore;
17 print foo(); # prints 'original sub'
18
20 The Problem
21 Sometimes subroutines need to be overridden. In fact, your author does
22 this constantly for tests. Particularly when testing, using a Mock
23 Object can be overkill when all you want to do is override one tiny,
24 little function.
25
26 Overriding a subroutine is often done with syntax similar to the
27 following.
28
29 {
30 local *Some::sub = sub {'some behavior'};
31 # do something
32 }
33 # original subroutine behavior restored
34
35 This has a few problems.
36
37 {
38 local *Get::some_feild = { 'some behavior' };
39 # do something
40 }
41
42 In the above example, not only have we probably mispelled the
43 subroutine name, but even if their had been a subroutine with that
44 name, we haven't overridden it. These two bugs can be subtle to
45 detect.
46
47 Further, if we're attempting to localize the effect by placing this
48 code in a block, the entire construct is cumbersome.
49
50 Hook::LexWrap also allows us to override sub behavior, but I can never
51 remember the exact syntax.
52
53 An easier way to replace subroutines
54 Instead, "Sub::Override" allows the programmer to simply name the sub
55 to replace and to supply a sub to replace it with.
56
57 my $override = Sub::Override->new('Some::sub', sub {'new data'});
58
59 # which is equivalent to:
60 my $override = Sub::Override->new;
61 $override->replace('Some::sub', sub { 'new data' });
62
63 You can replace multiple subroutines, if needed:
64
65 $override->replace('Some::sub1', sub { 'new data1' });
66 $override->replace('Some::sub2', sub { 'new data2' });
67 $override->replace('Some::sub3', sub { 'new data3' });
68
69 If replacing the subroutine succeeds, the object is returned. This
70 allows the programmer to chain the calls, if this style of programming
71 is preferred:
72
73 $override->replace('Some::sub1', sub { 'new data1' })
74 ->replace('Some::sub2', sub { 'new data2' })
75 ->replace('Some::sub3', sub { 'new data3' });
76
77 A subroutine may be replaced as many times as desired. This is most
78 useful when testing how code behaves with multiple conditions.
79
80 $override->replace('Some::thing', sub { 0 });
81 is($object->foo, 'wibble', 'wibble is returned if Some::thing is false');
82
83 $override->replace('Some::thing', sub { 1 });
84 is($object->foo, 'puppies', 'puppies are returned if Some::thing is true');
85
86 Restoring subroutines
87 If the object falls out of scope, the original subs are restored.
88 However, if you need to restore a subroutine early, just use the
89 restore method:
90
91 my $override = Sub::Override->new('Some::sub', sub {'new data'});
92 # do stuff
93 $override->restore;
94
95 Which is somewhat equivalent to:
96
97 {
98 my $override = Sub::Override->new('Some::sub', sub {'new data'});
99 # do stuff
100 }
101
102 If you have override more than one subroutine with an override object,
103 you will have to explicitly name the subroutine you wish to restore:
104
105 $override->restore('This::sub');
106
107 Note "restore()" will always restore the original behavior of the
108 subroutine no matter how many times you have overridden it.
109
110 Which package is the subroutine in?
111 Ordinarily, you want to fully qualify the subroutine by including the
112 package name. However, failure to fully qualify the subroutine name
113 will assume the current package.
114
115 package Foo;
116 use Sub::Override;
117 sub foo { 23 };
118 my $override = Sub::Override->new( foo => sub { 42 } ); # assumes Foo::foo
119 print foo(); # prints 42
120 $override->restore;
121 print foo(); # prints 23
122
124 new
125 my $sub = Sub::Override->new;
126 my $sub = Sub::Override->new($sub_name, $sub_ref);
127
128 Creates a new "Sub::Override" instance. Optionally, you may override a
129 subroutine while creating a new object.
130
131 replace
132 $sub->replace($sub_name, $sub_body);
133
134 Temporarily replaces a subroutine with another subroutine. Returns the
135 instance, so chaining the method is allowed:
136
137 $sub->replace($sub_name, $sub_body)
138 ->replace($another_sub, $another_body);
139
140 This method will "croak" is the subroutine to be replaced does not
141 exist.
142
143 override
144 my $sub = Sub::Override->new;
145 $sub->override($sub_name, $sub_body);
146
147 "override" is an alternate name for "replace". They are the same
148 method.
149
150 restore
151 $sub->restore($sub_name);
152
153 Restores the previous behavior of the subroutine. This will happen
154 automatically if the "Sub::Override" object falls out of scope.
155
157 None by default.
158
160 Probably. Tell me about 'em.
161
163 · Hook::LexWrap -- can also override subs, but with different
164 capabilities
165
166 · Test::MockObject -- use this if you need to alter an entire class
167
169 Curtis "Ovid" Poe, "<ovid [at] cpan [dot] org>"
170
171 Reverse the name to email me.
172
174 Copyright (C) 2004-2005 by Curtis "Ovid" Poe
175
176 This library is free software; you can redistribute it and/or modify it
177 under the same terms as Perl itself, either Perl version 5.8.2 or, at
178 your option, any later version of Perl 5 you may have available.
179
180
181
182perl v5.12.0 2005-09-21 Sub::Override(3)