Is there a way to override a Perl "use constant" in your unit testing?

When using constants they are implemented as constant functions behaving something like:

use subs 'BASE_PATH';
sub BASE_PATH () {"/data/monitor/"}

Any uses of BASE_PATH in the program are inlined and so can't be modified.

To achieve similar you could manually use the subs pragma (to make BASE_PATH behave as a built in function) and declare BASE_PATH as a standard function:

use subs 'BASE_PATH';
sub BASE_PATH {"/data/monitor/"}

print "BASE_PATH is ".BASE_PATH."\n";

*BASE_PATH = sub {"/new/path"};
print "BASE_PATH is ".BASE_PATH."\n";

Although why you would want to do this I'm not too sure.


Tests often reveal inflexibility in the design. This is one of those times. That constant shouldn't be constant.

If you're doing it for performance reasons I'm willing to bet hard currency that it doesn't make any difference.


package My::Class;

use constant BASE_PATH => "/a/real/value/";

# ..more code here..

1;

Now in your unit tests:

use My::Class;
*{My::Class::BASE_PATH} = sub { "/a/fake/value" };

# do your tests here...