Mr. Conway’s book suggests that constants are good but “use constant;” is the wrong way to go about them. It suggests the Readonly module. Later commenters have suggested Const::Fast instead. Feh, I say.
The arguments made against “use constant” are that all cap constants look funny and people are surprised when they don’t interpolate right. I find this a tenuous argument, as they’re visibly different from variables that do interpolate.
I also dislike the variable-looking constants because they aren’t actually variables any more. If I try and do things to them that I should be able to do to variables, the program will crash, usually at run-time.
The book suggests creating a constant – a variable that isn’t actually a variable, mind you – for the empty string, as it will be less ambiguous than a set of empty quotes, and more familiar to a less-experienced engineer than the ugly q{} notation. Except they’ll all be different – there isn’t a standard, so we’ll have $BLANK, $EMPTY_STRING, $EMPTY, $NULL, $QUOTEQUOTE, and any number of other wacky variants that different engineers come up with. Boo! Use an empty string and be done!
I like constants, and think they should be used. I think putting things in constants helps make programs more readable and prevents gobs of magic numbers from making expressions unfathomable. But I don’t like the mechanisms offered by the book, when the language comes with a perfectly usable mechanism to create constants.
I disable the perlcritic complaint about use constant. Sometimes I disable or reconfigure the one about constants in general. The lack of -1 in the list of acceptable constants bites me often. Let’s invert the sign! Whoops, can’t multiply by -1, that’s not allowed. Let’s get the last item in a string! Whoops, -1 isn’t allowed. I often add that to the list of allowed constants.
In Perl personally I just find that “my $SOME_CONST = ‘foo'” etc works best. Its a well-known convention that all-caps means constant, it works in many languages; I find “use constant” and Readonly in Perl to be an unnecessary complication.
https://github.com/Perl-Critic/Perl-Critic/issues/500
Thanks for the Const::Fast recommendation!
It is actually awkward that “use constant” constants don’t interpolate– that’s one of a number of drawbacks to using them.
It is kind of cool that the perl compiler knows how to optimize them and turn them into in-line values, but it’s unlikely to matter much in any real case.
Uppercase vars for constants isn’t a bad idea, though to my eye it implies that they’re package globals… (I gather Conway’s take is that uppercase just means “there’s something funny here”, so maybe it’s just me).
Constants are one of those little issues in perl that really should be a lot more boring than they are.