NAME
readonly - Perl pragma and function module to create readonly scalars
SYNOPSIS
##### Compile time -- create, assign & set readonly in one step
use readonly
'$MAX_LINES' => 70,
'$TOPIC' => 'computing',
'$TRUE' => 1,
'$FALSE' => 0,
'$PI' => 4 * atan2( 1, 1 ),
'$ALPHA' => 1.761,
'$BETA' => 2.814,
'$GAMMA' => 4.012,
'$PATH' => '/usr/local/lib/project/include',
'$EXE' => '/usr/local/bin/project',
;
# Have to use a separate readonly if we refer back.
use readonly '$RC' => "$EXE/config" ;
$RC = '/new/path' ; # eval trappable error
##### Run time -- set readonly
use readonly () ; # If no previous pragma calls.
use vars qw( $BACKGROUND $FOREGROUND $HIGHLIGHT ) ; # Predeclare.
$BACKGROUND = param( 'green' ) ; # Pre-assign
$FOREGROUND = param( 'blue' ) ;
$HIGHLIGHT = param( 'yellow' ) ;
readonly->set( '$BACKGROUND', '$FOREGROUND', '$HIGHLIGHT' ) ;
$BACKGROUND = 'red' ; # eval trappable error
DESCRIPTION
The readonly module can be used either as a compile-time pragma or a run-time class module.
When used as a pragma it creates readonly scalars in the current namespace. When used as a function module it marks scalars as readonly. Only package scalars may be made readonly, not my
scalars. readonly
scalars 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.
The pragma, constant
, provides apparently similar functionality (and more, since constant
also handles arrays, hashes etc). However constant
s are not readonly scalars, but rather subroutines which behave like them and which must be used with different syntaxes in different contexts. readonly
s can be used with the same consistent scalar syntax throughout. Also readonly
s may be set either at compile-time or at run-time.
String Interpolation
use readonly '$PI' => 4 * atan2 1, 1 ; # Compile time
use constant PI => 4 * atan2 1, 1 ; # Compile time
We can print readonly
s directly:
print "The value of pi is $PI\n" ;
but for constant
s we must do this:
print "The value of pi is ", PI, "\n" ;
or this:
print "The value of pi is @{[PI]}\n" ;
Hash Keys
use readonly '$TOPIC' => 'geology' ;
use constant TOPIC => 'geology' ;
my %topic = (
geology => 5,
computing => 7,
biology => 9,
) ;
Using a readonly
scalar we can simply write:
my $value = $topic{$TOPIC}
however, 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} ;
Runtime readonly's
Sometimes we only know what the readonly value will be after performing some of our execution; in such cases we can use readonly->set
to make an existing scalar readonly:
use readonly () ; # If not already use'd
use vars qw( $RED $GREEN $BLUE $YELLOW ) ; # Predeclare
$RED = '#FF0000' ; # Pre-assign
$GREEN = '#00FF00' ;
$BLUE = '#0000FF' ;
$YELLOW = '#FFFF00' ;
readonly->set( '$RED', '$GREEN', '$BLUE', '$YELLOW' ) ;
BUGS
Only copes with scalars.
In some tests with 5.004 readonly->set
gives spurious warnings.
Sometimes with 5.004 when using eval exception handling you get "Use of uninitialized value at..." errors; the cure is to write:
eval {
$@ = undef ;
# rest as normal
AUTHOR
Mark Summerfield. I can be contacted as <summer@perlpress.com> - please include the word 'readonly' in the subject line.
I copied some ideas from constant.pm
.
COPYRIGHT
Copyright (c) Mark Summerfield 2000. All Rights Reserved.
This module may be used/distributed/modified under the same terms as perl itself.
SEE ALSO
Constant or readonly scalars, arrays and hashes are available through other mechanisms:
Tom Phoenix's standard module
constant
. This has the cons described above, but the pros that it can provide readonly arrays and may be faster than other approaches because the perl compiler cooperates with it behind the scenes.Graham Barr's tie-based code archived at http://www.xray.mpe.mpg.de/mailing-lists/modules/1999-02/msg00090.html
Mark-Jason Dominus' tie-based code at http://www.plover.com/~mjd/perl/Locked/
My own tie-based code at http://www.perlpress.com/perl/antiques.html Tie::Const.
Tie-based implementations should be able to offer readonly scalars, arrays and hashes, but these implementations are likely to have a performance overhead compared with readonly
or constant
.