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.