NAME
readonly - Perl pragma to declare readonly scalars
SYNOPSIS
use readonly '$READONLY' => 57 ;
use readonly '$TOPIC' => 'computing' ;
use readonly '$TRUE' => 1 ;
use readonly '$FALSE' => 0 ;
use readonly '$PI' => 4 * atan2 1, 1 ;
use readonly
'$ALPHA' => 1.761,
'$BETA' => 2.814,
'$GAMMA' => 4.012,
'$PATH' => '/usr/local/lib/lout/include',
'$EXE' => '/usr/local/bin/lout',
;
use readonly '$BASE' => '/usr/opt/mozilla' ;
# Have to use a separate readonly if we refer back.
use readonly
'$RC' => "$BASE/config",
'$EXE' => "$BASE/bin",
;
DESCRIPTION
This pragma creates readonly scalars in the current namespace. The scalars thus created may be used in all contexts where read/write scalars would be used with the exception that you will get an eval
trappable run-time error "Modification of a read-only value attempted..." if you try to assign to a readonly scalar.
Of course there is already a pragma, constant
, which provides this kind of functionality (and more, since constant
also handles arrays, hashes etc). However constant
s must be used with different syntax in different contexts, whereas readonly
s can be used with the same consistent scalar syntax throughout.
String interpolation
use constant PI => 4 * atan2 1, 1 ;
use readonly '$PI' => 4 * atan2 1, 1 ;
We cannot print constant
s directly so we must do this:
print "The value of pi is ", PI, "\n" ;
or this:
print "The value of pi is @{[PI]}\n" ;
but we can print readonly
s directly:
print "The value of pi is $PI\n" ;
Hash keys
use constant TOPIC => 'geology' ;
use readonly '$TOPIC' => 'geology' ;
my %topic = (
geology => 5,
computing => 7,
biology => 9,
) ;
If we try to access one of the hash elements using the constant
:
my $value = $topic{TOPIC} ;
we get an unwelcome surprise: $value
is set to undef
because perl will take TOPIC to be the literal string 'TOPIC' and since no hash element has that key the result is undef. Thus in this situation we would have to write:
my $value = $topic{TOPIC()} ;
or perhaps:
my $value = $topic{&TOPIC} ;
On the other hand if we use a readonly
scalar we can simply write:
my $value = $topic{$TOPIC}
with no problems.
Error reporting
PI = 3 ;
will lead to a compile-time error, "Can't modify constant item in scalar assignment...", whereas
$PI = 3 ;
will lead to a run-time error, "Modification of a read-only value attempted...".
Is it necessary?
You can achieve the same effect as:
use readonly '$WEB_ADDRESS' => 'www.perlpress.com' ;
by coding:
use vars '$WEB_ADDRESS' ; *WEB_ADDRESS = \'www.perlpress.com' ;
Similarly:
use constant WEB_ADDRESS => 'www.perlpress.com' ;
can be coded as:
sub WEB_ADDRESS() { 'www.perlpress.com' } # No semi-colon.
However, readonly
allows us to create many readonly scalars in one go with a compact syntax:
use readonly
'$HOME' => '/home/summer',
'$ROOT' => '/root',
'$PERL' => '/usr/lib/perl',
;
BUGS
Only copes with scalars.
Strings which contain \'s will have them removed.
Silently ignores attempted redeclarations, e.g.
use readonly '$READONLY' => 5 ;
...
use readonly '$READONLY' => 9 ;
$READONLY
is still 5, but no error message is given.
AUTHOR
I copied some ideas from constant.pm
.
Mark Summerfield. I can be contacted as <summer@perlpress.com> - please include the word 'readonly' in the subject line.
COPYRIGHT
Copyright (c) Mark Summerfield 2000. All Rights Reserved.
This module may be used/distributed/modified under the same terms as perl itself.