=head1 NAME readonly - Perl pragma to declare readonly scalars =head1 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", ; =head1 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 C 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, C, which provides this kind of functionality (and more, since C also handles arrays, hashes etc). However Cs must be used with different syntax in different contexts, whereas Cs can be used with the same consistent scalar syntax throughout. =head2 String interpolation use constant PI => 4 * atan2 1, 1 ; use readonly '$PI' => 4 * atan2 1, 1 ; We cannot print Cs 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 Cs directly: print "The value of pi is $PI\n" ; =head2 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 C: my $value = $topic{TOPIC} ; we get an unwelcome surprise: C<$value> is set to C 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 C scalar we can simply write: my $value = $topic{$TOPIC} with no problems. =head2 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...". =head2 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, C 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', ; =head1 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 ; C<$READONLY> is I 5, but no error message is given. =head1 AUTHOR I copied some ideas from C. Mark Summerfield. I can be contacted as - please include the word 'readonly' in the subject line. =head1 COPYRIGHT Copyright (c) Mark Summerfield 2000. All Rights Reserved. This module may be used/distributed/modified under the same terms as perl itself. =cut