NAME
Tie::Const - Perl module to provide constant scalars and hashes.
SYNOPSIS
use Tie::Const ; # Imports const.
const my $SCALAR1 => 10 ;
use Tie::Const qw( const reconst unconst ) ; # Or "use Tie::Const ':ALL' ;"
const my $SCALAR2 => "Hello" ; # Note the =>, NOT =.
const my $SCALAR3 => 42 ;
const $SCALAR4 => $SCALAR3 ;
reconst $SCALAR4 => 57 ;
unconst $SCALAR4 ;
We can't use "my" to declare constant hashes directly so do the my first.
my %HASH1 ;
const \%HASH1 => \%HASH2 ; # Note that the first must be a reference.
my( %HASH3, %HASH4 ) ;
const \%HASH3 => ( a => 1, b => 2, c => 3 ) ; # Can pass literal hash
const \%HASH4 => { a => 1, b => 2, c => 3 } ; # or hash ref.
reconst \%HASH4 => ( %HASH4, d => 4, e => 5 ) ;
unconst \%HASH4 ;
DESCRIPTION
Constant Scalars
use Tie::Const ':ALL' ; # or "use Tie::Const qw( const reconst unconst ) ;"
const my $CONSTANT => "Hello" ;
my $var = $CONSTANT . "\n" ;
my $val = $hash{$CONSTANT} ;
print "$CONSTANT World" ;
Constants declared with const
look and behave like ordinary variables and can be used anywhere a variable is used except that you can't overwrite them. (You can however redefine them with reconst
, or turn them back into ordinary variables again with unconst
.)
use Tie::Const qw( const reconst unconst ) ;
Create a new scalar variable.
my $SCALAR = "Hello" ;
We can modify it anytime.
$SCALAR .= " World" ;
Make that scalar variable a constant, assigning it a value.
const $SCALAR => $SCALAR ;
Any attempt to overwrite $SCALAR
's value will result in a trappable (with eval) runtime error, so from here on in we are guaranteed that no-one can change $SCALAR
's value.
However, why merely embrace the definition of const that applies in other computer languages when we can do so much more in Perl? It may be that we want a variable to be constant most of the time, but in certain circumstances we would like it to be changed. We can redefine its value using reconst
.
reconst $SCALAR => $SCALAR . "!\n" ;
$SCALAR
is still read-only, but now it has a new constant value.
It may occur however that we have reached a point where we want it to be an ordinary variable after all. There are two ways of achieving that. One way is to use unconst
.
unconst $SCALAR ;
$SCALAR
is now an ordinary variable again, and its value is the value it held when it was made const
, or last reconst
'ed. If you don't want to preserve the value you can untie it instead.
untie $SCALAR ; # Works now but deprecated so don't rely on it.
The value that $SCALAR
holds now is the last value assigned to it before it was made const
which could be undef
if it was defined and declared at the same time. Do not rely on this behaviour; you should assume that an untie'd const must be redefined before reusing it.
Thus in subroutines where we would normally write:
my $value = shift ;
or similar, we can now write
const my $value = shift ;
to make it clear we only want to read the value not write to it.
Constant Hashes
use Tie::Const qw( const reconst unconst ) ;
Create a new hash variable.
my %HASH ;
Make that variable a constant and assign to it.
const \%HASH => ( cyan => 4, magenta => 5, yellow => 6, black => 7 ) ;
Any attempt to overwrite any of %HASH
's values or to clear %HASH
itself will result in a trappable (with eval) runtime error, so from here on in we are guaranteed that no-one can change %HASH
or its values. Unless we reconst
it of course.
reconst \%HASH => ( %HASH, red => 1, green => 2, blue => 3 ) ;
%HASH
is still read-only, but now it has new constant values.
We can unconst
a hash just like a scalar.
unconst \%HASH ;
%HASH
is now an ordinary variable again, and its values are the values it held when it was made const
, or last reconst
'ed. If you don't want to preserve the values you can untie it instead. (This is more efficient.)
untie %HASH ; # Works now but deprecated so don't rely on it.
Constant elements of non-const hashes
Individual elements of non-const hashes can be made constant. They can be reconst
'ed and unconst
'ed too of course. But beware that if the non-const hash is cleared the const(s) will be lost along with it! Also const hash elements can be deleted.
Warning: const hash elements can be deleted by %HASH = ()
and by delete $HASH{$KEY}
.
const $HASH{$KEY} => "hash" ;
WHY ANOTHER CONSTANT MODULE?
Although Perl is my favourite programming language I find it annoying that constants are not a built-in part of the language. For non-trivial programs I feel that constants are a real help. Hopefully one day they'll be part of the core language - maybe using the syntax offered here?
You can of course declare constants like this:
sub CONSTANT () { "Constant" }
I am not keen on this approach because to get the values of your constants you have to write them in one of several different ways depending on the context. For example if I want to use the constant that I've just declared above in an expression I can use it like this:
my $var = CONSTANT . "\n" ;
This looks nice for C programmers. But if I want to use it as a hash key I must use one of the following approaches so that it isn't treated as the bareword CONSTANT
and converted by perl into the literal "CONSTANT"
:
my $key = $hash{CONSTANT()} ;
my $key = $hash{&CONSTANT} ;
And if I want to print the constant I have to use yet another syntax:
print "@{[CONSTANT]}\n"
I wanted to be able to define a constant in such a way that I can use it in any context that a variable can appear using a single syntax. Hence I wrote this module.
EXAMPLES
(See DESCRIPTION.)
BUGS
Perl has a few built-in hashes, e.g. @ARGV
, %ENV
, and many built-in scalars, e.g. $_
.
I would not recommend applying const
to any built-in scalar or hash with the possible exception of %ENV
!
The only built-in hash which it might be sensible to apply const
to is %ENV
; who knows it might even make a script slightly more secure in some cases?
const \%ENV => \%ENV ; # This seems OK.
You can even apply const
to particular keys of a non-const hash.
const $ENV{PATH} => '/usr/bin:/usr/local/bin' ;
Arrays are not included because support for tied arrays in Perl 5.004 is too incomplete.
Hashes also have some problems: if a non-const hash is cleared any const scalars in the non-const hash will be lost along with it! Also const hash elements can be deleted.
CHANGES
1998/6/18 First release.
1998/6/25 First public release.
1999/01/18 Second public release. Arrays dropped: too incomplete.
1999/07/29 Third release. Minor changes.
1999/07/30 No effective changes. Corrections for CPAN and automatic testing.
1999/08/08 Changed licence to LGPL.
1999/09/09 Renamed package Tie::Const.pm as per John Porter's (CPAN) suggestion.
AUTHOR
Mark Summerfield. I can be contacted as <summer@chest.ac.uk> - please include the word 'const' in the subject line.
COPYRIGHT
Copyright (c) Mark Summerfield 1998/9. All Rights Reserved.
This module may be used/distributed/modified under the LGPL.