=head1 NAME readonly - Perl pragma and function module to create readonly scalars =head1 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 =head1 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, I C scalars. C scalars 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. The pragma, C, provides apparently similar functionality (and more, since C also handles arrays, hashes etc). However Cs are I readonly scalars, but rather subroutines which behave like them and which must be used with different syntaxes in different contexts. Cs can be used with the same consistent scalar syntax throughout. Also Cs may be set either at compile-time I at run-time. =head2 String Interpolation use readonly '$PI' => 4 * atan2 1, 1 ; # Compile time use constant PI => 4 * atan2 1, 1 ; # Compile time We can print Cs directly: print "The value of pi is $PI\n" ; but for Cs we must do this: print "The value of pi is ", PI, "\n" ; or this: print "The value of pi is @{[PI]}\n" ; =head2 Hash Keys use readonly '$TOPIC' => 'geology' ; use constant TOPIC => 'geology' ; my %topic = ( geology => 5, computing => 7, biology => 9, ) ; Using a C scalar we can simply write: my $value = $topic{$TOPIC} however, 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} ; =head2 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 Cset> 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' ) ; =head1 BUGS Only copes with scalars. In some tests with 5.004 Cset> 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 =head1 AUTHOR Mark Summerfield. I can be contacted as - please include the word 'readonly' in the subject line. I copied some ideas from C. =head1 COPYRIGHT Copyright (c) Mark Summerfield 2000. All Rights Reserved. This module may be used/distributed/modified under the same terms as perl itself. =head1 SEE ALSO Constant or readonly scalars, arrays and hashes are available through other mechanisms: =over 4 =item * Tom Phoenix's standard module C. 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. =item * Graham Barr's tie-based code archived at http://www.xray.mpe.mpg.de/mailing-lists/modules/1999-02/msg00090.html =item * Mark-Jason Dominus' tie-based code at http://www.plover.com/~mjd/perl/Locked/ =item * My own tie-based code at http://www.perlpress.com/perl/antiques.html Tie::Const. =back 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 C or C. =cut