I just ran a quick test on 5.8 to ensure that there were no problems with inheriting constants and, as far as I can tell, there aren't any, but I do worry about it because of issues like this:
$ perl -MO=Deparse -e 'sub foo(){3};print foo()'
print 3;
Note that the sub declaration is gone and, due to the constant folding optimization, the value of the constant is hardcoded into the program at compile time. As a result, I tend to avoid constants if they're to be used outside of a given package. For example, I used to do this:
use constant DEBUGGING => 0;
# later
if (DEBUGGING) {...}
I would try to override DEBUGGING in a test suite ...
local *Some::Package::DEBUGGING = sub {0};
... only to discover that because use of the constant had been optimized away, there was nothing left to override. I've personally found that bugs like this can be very difficult for me to debug as these are "behind the scenes" compile-time actions. I wound up sticking explicit sub declarations (with no prototype) in my code and my problems went away.
In other words, I use the constant pragma quite a bit, but again, only if said constant isn't to be used outside of a given package (or is to be explicitly exported to another package).
My coworker and I had quite a bit of debate about these issues and whether or not to use constants, but what finally settled it was simple: these are properties of a class, so we should provide accessors to them and ensure that the interface to class data is consistent. The only consideration we gave to the special case is that the accessors are ALL CAPS, which should be a clue to any programmer that there's something odd going on.
Cheers,
Ovid
New address of my CGI Course.
Silence is Evil (feel free to copy and distribute widely - note copyright text) |