1Sub::Override(3)      User Contributed Perl Documentation     Sub::Override(3)
2
3
4

NAME

6       Sub::Override - Perl extension for easily overriding subroutines
7

VERSION

9       0.09
10

SYNOPSIS

12         use Sub::Override;
13
14         sub foo { 'original sub' };
15         print foo(); # prints 'original sub'
16
17         my $override = Sub::Override->new( foo => sub { 'overridden sub' } );
18         print foo(); # prints 'overridden sub'
19         $override->restore;
20         print foo(); # prints 'original sub'
21

DESCRIPTION

23   The Problem
24       Sometimes subroutines need to be overridden.  In fact, your author does
25       this constantly for tests.  Particularly when testing, using a Mock
26       Object can be overkill when all you want to do is override one tiny,
27       little function.
28
29       Overriding a subroutine is often done with syntax similar to the
30       following.
31
32        {
33          local *Some::sub = sub {'some behavior'};
34          # do something
35        }
36        # original subroutine behavior restored
37
38       This has a few problems.
39
40        {
41          local *Get::some_feild = { 'some behavior' };
42          # do something
43        }
44
45       In the above example, not only have we probably misspelled the
46       subroutine name, but even if their had been a subroutine with that
47       name, we haven't overridden it.  These two bugs can be subtle to
48       detect.
49
50       Further, if we're attempting to localize the effect by placing this
51       code in a block, the entire construct is cumbersome.
52
53       Hook::LexWrap also allows us to override sub behavior, but I can never
54       remember the exact syntax.
55
56   An easier way to replace subroutines
57       Instead, "Sub::Override" allows the programmer to simply name the sub
58       to replace and to supply a sub to replace it with.
59
60         my $override = Sub::Override->new('Some::sub', sub {'new data'});
61
62         # which is equivalent to:
63         my $override = Sub::Override->new;
64         $override->replace('Some::sub', sub { 'new data' });
65
66       You can replace multiple subroutines, if needed:
67
68         $override->replace('Some::sub1', sub { 'new data1' });
69         $override->replace('Some::sub2', sub { 'new data2' });
70         $override->replace('Some::sub3', sub { 'new data3' });
71
72       If replacing the subroutine succeeds, the object is returned.  This
73       allows the programmer to chain the calls, if this style of programming
74       is preferred:
75
76         $override->replace('Some::sub1', sub { 'new data1' })
77                  ->replace('Some::sub2', sub { 'new data2' })
78                  ->replace('Some::sub3', sub { 'new data3' });
79
80       If the subroutine has a prototype, the new subroutine should be
81       declared with same prototype as original one:
82
83         $override->replace('Some::sub_with_proto', sub ($$) { ($_[0], $_ [1]) });
84
85       A subroutine may be replaced as many times as desired.  This is most
86       useful when testing how code behaves with multiple conditions.
87
88         $override->replace('Some::thing', sub { 0 });
89         is($object->foo, 'wibble', 'wibble is returned if Some::thing is false');
90
91         $override->replace('Some::thing', sub { 1 });
92         is($object->foo, 'puppies', 'puppies are returned if Some::thing is true');
93
94   Restoring subroutines
95       If the object falls out of scope, the original subs are restored.
96       However, if you need to restore a subroutine early, just use the
97       restore method:
98
99         my $override = Sub::Override->new('Some::sub', sub {'new data'});
100         # do stuff
101         $override->restore;
102
103       Which is somewhat equivalent to:
104
105         {
106           my $override = Sub::Override->new('Some::sub', sub {'new data'});
107           # do stuff
108         }
109
110       If you have override more than one subroutine with an override object,
111       you will have to explicitly name the subroutine you wish to restore:
112
113         $override->restore('This::sub');
114
115       Note "restore()" will always restore the original behavior of the
116       subroutine no matter how many times you have overridden it.
117
118   Which package is the subroutine in?
119       Ordinarily, you want to fully qualify the subroutine by including the
120       package name.  However, failure to fully qualify the subroutine name
121       will assume the current package.
122
123         package Foo;
124         use Sub::Override;
125         sub foo { 23 };
126         my $override = Sub::Override->new( foo => sub { 42 } ); # assumes Foo::foo
127         print foo(); # prints 42
128         $override->restore;
129         print foo(); # prints 23
130

METHODS

132   new
133         my $sub = Sub::Override->new;
134         my $sub = Sub::Override->new($sub_name, $sub_ref);
135
136       Creates a new "Sub::Override" instance.  Optionally, you may override a
137       subroutine while creating a new object.
138
139   replace
140        $sub->replace($sub_name, $sub_body);
141
142       Temporarily replaces a subroutine with another subroutine.  Returns the
143       instance, so chaining the method is allowed:
144
145        $sub->replace($sub_name, $sub_body)
146            ->replace($another_sub, $another_body);
147
148       This method will "croak" is the subroutine to be replaced does not
149       exist.
150
151   override
152        my $sub = Sub::Override->new;
153        $sub->override($sub_name, $sub_body);
154
155       "override" is an alternate name for "replace".  They are the same
156       method.
157
158   restore
159        $sub->restore($sub_name);
160
161       Restores the previous behavior of the subroutine.  This will happen
162       automatically if the "Sub::Override" object falls out of scope.
163

EXPORT

165       None by default.
166

BUGS

168       Probably.  Tell me about 'em.
169

SEE ALSO

171       ·   Hook::LexWrap -- can also override subs, but with different
172           capabilities
173
174       ·   Test::MockObject -- use this if you need to alter an entire class
175

AUTHOR

177       Curtis "Ovid" Poe, "<ovid [at] cpan [dot] org>"
178
179       Reverse the name to email me.
180
182       Copyright (C) 2004-2005 by Curtis "Ovid" Poe
183
184       This library is free software; you can redistribute it and/or modify it
185       under the same terms as Perl itself, either Perl version 5.8.2 or, at
186       your option, any later version of Perl 5 you may have available.
187
188
189
190perl v5.32.0                      2020-07-28                  Sub::Override(3)
Impressum