root/trunk/system/perl_lib/Readonly.pm

Revision 2306, 21.9 kB (checked in by cjg, 2 years ago)
  • Added Readonly.pm
Line 
1 =for gpg
2 -----BEGIN PGP SIGNED MESSAGE-----
3 Hash: SHA1
4
5 - -----BEGIN PGP SIGNED MESSAGE-----
6 Hash: SHA1
7
8 =head1 NAME
9
10 Readonly - Facility for creating read-only scalars, arrays, hashes.
11
12 =head1 VERSION
13
14 This documentation describes version 1.03 of Readonly.pm, April 20, 2004.
15
16 =cut
17
18 # Rest of documentation is after __END__.
19
20 use 5.005;
21 use strict;
22 #use warnings;
23 #no warnings 'uninitialized';
24
25 package Readonly;
26 $Readonly::VERSION = '1.03';    # Also change in the documentation!
27
28 # Autocroak (Thanks, MJD)
29 # Only load Carp.pm if module is croaking.
30 sub croak
31 {
32     require Carp;
33     goto &Carp::croak;
34 }
35
36 # These functions may be overridden by Readonly::XS, if installed.
37 sub is_sv_readonly   ($) { 0 }
38 sub make_sv_readonly ($) { die "make_sv_readonly called but not overridden" }
39 use vars qw/$XSokay/;     # Set to true in Readonly::XS, if available
40
41 # Common error messages, or portions thereof
42 use vars qw/$MODIFY $REASSIGN $ODDHASH/;
43 $MODIFY   = 'Modification of a read-only value attempted';
44 $REASSIGN = 'Attempt to reassign a readonly';
45 $ODDHASH  = 'May not store an odd number of values in a hash';
46
47 # See if we can use the XS stuff.
48 $Readonly::XS::MAGIC_COOKIE = "Do NOT use or require Readonly::XS unless you're me.";
49 eval 'use Readonly::XS';
50
51
52 # ----------------
53 # Read-only scalars
54 # ----------------
55 package Readonly::Scalar;
56
57 sub TIESCALAR
58 {
59     my $whence = (caller 2)[3];    # Check if naughty user is trying to tie directly.
60     Readonly::croak "Invalid tie"  unless $whence && $whence =~ /^Readonly::(?:Scalar1?|Readonly)$/;
61     my $class = shift;
62     Readonly::croak "No value specified for readonly scalar"        unless @_;
63     Readonly::croak "Too many values specified for readonly scalar" unless @_ == 1;
64
65     my $value = shift;
66     return bless \$value, $class;
67 }
68
69 sub FETCH
70 {
71     my $self = shift;
72     return $$self;
73 }
74
75 *STORE = *UNTIE =
76     sub {Readonly::croak $Readonly::MODIFY};
77
78
79 # ----------------
80 # Read-only arrays
81 # ----------------
82 package Readonly::Array;
83
84 sub TIEARRAY
85 {
86     my $whence = (caller 1)[3];    # Check if naughty user is trying to tie directly.
87     Readonly::croak "Invalid tie"  unless $whence =~ /^Readonly::Array1?$/;
88     my $class = shift;
89     my @self = @_;
90
91     return bless \@self, $class;
92 }
93
94 sub FETCH
95 {
96     my $self  = shift;
97     my $index = shift;
98     return $self->[$index];
99 }
100
101 sub FETCHSIZE
102 {
103     my $self = shift;
104     return scalar @$self;
105 }
106
107 BEGIN {
108     eval q{
109         sub EXISTS
110            {
111            my $self  = shift;
112            my $index = shift;
113            return exists $self->[$index];
114            }
115     } if $] >= 5.006;    # couldn't do "exists" on arrays before then
116 }
117
118 *STORE = *STORESIZE = *EXTEND = *PUSH = *POP = *UNSHIFT = *SHIFT = *SPLICE = *CLEAR = *UNTIE =
119     sub {Readonly::croak $Readonly::MODIFY};
120
121
122 # ----------------
123 # Read-only hashes
124 # ----------------
125 package Readonly::Hash;
126
127 sub TIEHASH
128 {
129     my $whence = (caller 1)[3];    # Check if naughty user is trying to tie directly.
130     Readonly::croak "Invalid tie"  unless $whence =~ /^Readonly::Hash1?$/;
131
132     my $class = shift;
133     # must have an even number of values
134     Readonly::croak $Readonly::ODDHASH unless (@_ %2 == 0);
135
136     my %self = @_;
137     return bless \%self, $class;
138 }
139
140 sub FETCH
141 {
142     my $self = shift;
143     my $key  = shift;
144
145     return $self->{$key};
146 }
147
148 sub EXISTS
149 {
150     my $self = shift;
151     my $key  = shift;
152     return exists $self->{$key};
153 }
154
155 sub FIRSTKEY
156 {
157     my $self = shift;
158     my $dummy = keys %$self;
159     return scalar each %$self;
160 }
161
162 sub NEXTKEY
163 {
164     my $self = shift;
165     return scalar each %$self;
166 }
167
168 *STORE = *DELETE = *CLEAR = *UNTIE =
169     sub {Readonly::croak $Readonly::MODIFY};
170
171
172 # ----------------------------------------------------------------
173 # Main package, containing convenience functions (so callers won't
174 # have to explicitly tie the variables themselves).
175 # ----------------------------------------------------------------
176 package Readonly;
177 use Exporter;
178 use vars qw/@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS/;
179 push @ISA, 'Exporter';
180 push @EXPORT, qw/Readonly/;
181 push @EXPORT_OK, qw/Scalar Array Hash Scalar1 Array1 Hash1/;
182
183 # Predeclare the following, so we can use them recursively
184 sub Scalar ($$);
185 sub Array (\@;@);
186 sub Hash (\%;@);
187
188 # Returns true if a string begins with "Readonly::"
189 # Used to prevent reassignment of Readonly variables.
190 sub _is_badtype
191 {
192     my $type = $_[0];
193     return lc $type if $type =~ s/^Readonly:://;
194     return;
195 }
196
197 # Shallow Readonly scalar
198 sub Scalar1 ($$)
199 {
200     croak "$REASSIGN scalar" if is_sv_readonly $_[0];
201     my $badtype = _is_badtype (ref tied $_[0]);
202     croak "$REASSIGN $badtype" if $badtype;
203
204     # xs method: flag scalar as readonly
205     if ($XSokay)
206     {
207         $_[0] = $_[1];
208         make_sv_readonly $_[0];
209         return;
210     }
211
212     # pure-perl method: tied scalar
213     my $tieobj = eval {tie $_[0], 'Readonly::Scalar', $_[1]};
214     if ($@)
215     {
216         croak "$REASSIGN scalar" if substr($@,0,43) eq $MODIFY;
217         die $@;    # some other error?
218     }
219     return $tieobj;
220 }
221
222 # Shallow Readonly array
223 sub Array1 (\@;@)
224 {
225     my $badtype = _is_badtype (ref tied $_[0]);
226     croak "$REASSIGN $badtype" if $badtype;
227
228     my $aref = shift;
229     return tie @$aref, 'Readonly::Array', @_;
230 }
231
232 # Shallow Readonly hash
233 sub Hash1 (\%;@)
234 {
235     my $badtype = _is_badtype (ref tied $_[0]);
236     croak "$REASSIGN $badtype" if $badtype;
237
238     my $href = shift;
239
240     # If only one value, and it's a hashref, expand it
241     if (@_ == 1  &&  ref $_[0] eq 'HASH')
242     {
243         return tie %$href, 'Readonly::Hash', %{$_[0]};
244     }
245
246     # otherwise, must have an even number of values
247     croak $ODDHASH unless (@_%2 == 0);
248
249     return tie %$href, 'Readonly::Hash', @_;
250 }
251
252 # Deep Readonly scalar
253 sub Scalar ($$)
254 {
255     croak "$REASSIGN scalar" if is_sv_readonly $_[0];
256     my $badtype = _is_badtype (ref tied $_[0]);
257     croak "$REASSIGN $badtype" if $badtype;
258
259     my $value = $_[1];
260
261     # Recursively check passed element for references; if any, make them Readonly
262     foreach ($value)
263     {
264         if    (ref eq 'SCALAR') {Scalar my $v => $$_; $_ = \$v}
265         elsif (ref eq 'ARRAY')  {Array  my @v => @$_; $_ = \@v}
266         elsif (ref eq 'HASH')   {Hash   my %v =>  $_; $_ = \%v}
267     }
268
269     # xs method: flag scalar as readonly
270     if ($XSokay)
271     {
272         $_[0] = $value;
273         make_sv_readonly $_[0];
274         return;
275     }
276
277     # pure-perl method: tied scalar
278     my $tieobj = eval {tie $_[0], 'Readonly::Scalar', $value};
279     if ($@)
280     {
281         croak "$REASSIGN scalar" if substr($@,0,43) eq $MODIFY;
282         die $@;    # some other error?
283     }
284     return $tieobj;
285 }
286
287 # Deep Readonly array
288 sub Array (\@;@)
289 {
290     my $badtype = _is_badtype (ref tied @{$_[0]});
291     croak "$REASSIGN $badtype" if $badtype;
292
293     my $aref = shift;
294     my @values = @_;
295
296     # Recursively check passed elements for references; if any, make them Readonly
297     foreach (@values)
298     {
299         if    (ref eq 'SCALAR') {Scalar my $v => $$_; $_ = \$v}
300         elsif (ref eq 'ARRAY')  {Array  my @v => @$_; $_ = \@v}
301         elsif (ref eq 'HASH')   {Hash   my %v => $_;  $_ = \%v}
302     }
303     # Lastly, tie the passed reference
304     return tie @$aref, 'Readonly::Array', @values;
305 }
306
307 # Deep Readonly hash
308 sub Hash (\%;@)
309 {
310     my $badtype = _is_badtype (ref tied %{$_[0]});
311     croak "$REASSIGN $badtype" if $badtype;
312
313     my $href = shift;
314     my @values = @_;
315
316     # If only one value, and it's a hashref, expand it
317     if (@_ == 1  &&  ref $_[0] eq 'HASH')
318     {
319         @values = %{$_[0]};
320     }
321
322     # otherwise, must have an even number of values
323     croak $ODDHASH unless (@values %2 == 0);
324
325     # Recursively check passed elements for references; if any, make them Readonly
326     foreach (@values)
327     {
328         if    (ref eq 'SCALAR') {Scalar my $v => $$_; $_ = \$v}
329         elsif (ref eq 'ARRAY')  {Array  my @v => @$_; $_ = \@v}
330         elsif (ref eq 'HASH')   {Hash   my %v => $_;  $_ = \%v}
331     }
332
333     return tie %$href, 'Readonly::Hash', @values;
334 }
335
336
337 # Common entry-point for all supported data types
338 eval q{sub Readonly} . ( $] < 5.008 ? '' : '(\[$@%]@)' ) . <<'SUB_READONLY';
339 {
340     if (ref $_[0] eq 'SCALAR')
341     {
342         croak $MODIFY if is_sv_readonly ${$_[0]};
343         my $badtype = _is_badtype (ref tied ${$_[0]});
344         croak "$REASSIGN $badtype" if $badtype;
345         croak "Readonly scalar must have only one value" if @_ > 2;
346
347         my $tieobj = eval {tie ${$_[0]}, 'Readonly::Scalar', $_[1]};
348         # Tie may have failed because user tried to tie a constant, or we screwed up somehow.
349         if ($@)
350         {
351             croak $MODIFY if $@ =~ /^$MODIFY at/;    # Point the finger at the user.
352             die "$@\n";        # Not a modify read-only message; must be our fault.
353         }
354         return $tieobj;
355     }
356     elsif (ref $_[0] eq 'ARRAY')
357     {
358         my $aref = shift;
359         return Array @$aref, @_;
360     }
361     elsif (ref $_[0] eq 'HASH')
362     {
363         my $href = shift;
364         croak $ODDHASH  if @_%2 != 0  &&  !(@_ == 1  && ref $_[0] eq 'HASH');
365         return Hash %$href, @_;
366     }
367     elsif (ref $_[0])
368     {
369         croak "Readonly only supports scalar, array, and hash variables.";
370     }
371     else
372     {
373         croak "First argument to Readonly must be a reference.";
374     }
375 }
376 SUB_READONLY
377
378
379 1;
380 __END__
381
382 =head1 SYNOPSIS
383
384  use Readonly;
385
386  # Read-only scalar
387  Readonly::Scalar     $sca => $initial_value;
388  Readonly::Scalar  my $sca => $initial_value;
389
390  # Read-only array
391  Readonly::Array      @arr => @values;
392  Readonly::Array   my @arr => @values;
393
394  # Read-only hash
395  Readonly::Hash       %has => (key => value, key => value, ...);
396  Readonly::Hash    my %has => (key => value, key => value, ...);
397  # or:
398  Readonly::Hash       %has => {key => value, key => value, ...};
399
400  # You can use the read-only variables like any regular variables:
401  print $sca;
402  $something = $sca + $arr[2];
403  next if $has{$some_key};
404
405  # But if you try to modify a value, your program will die:
406  $sca = 7;
407  push @arr, 'seven';
408  delete $has{key};
409  # The error message is "Modification of a read-only value
410 attempted"
411
412  # Alternate form (Perl 5.8 and later)
413  Readonly    $sca => $initial_value;
414  Readonly my $sca => $initial_value;
415  Readonly    @arr => @values;
416  Readonly my @arr => @values;
417  Readonly    %has => (key => value, key => value, ...);
418  Readonly my %has => (key => value, key => value, ...);
419  # Alternate form (for Perls earlier than v5.8)
420  Readonly    \$sca => $initial_value;
421  Readonly \my $sca => $initial_value;
422  Readonly    \@arr => @values;
423  Readonly \my @arr => @values;
424  Readonly    \%has => (key => value, key => value, ...);
425  Readonly \my %has => (key => value, key => value, ...);
426
427
428 =head1 DESCRIPTION
429
430 This is a facility for creating non-modifiable variables.  This is
431 useful for configuration files, headers, etc.  It can also be useful
432 as a development and debugging tool, for catching updates to variables
433 that should not be changed.
434
435 If any of the values you pass to C<Scalar>, C<Array>, or C<Hash> are
436 references, then those functions recurse over the data structures,
437 marking everything as Readonly.  Usually, this is what you want: the
438 entire structure nonmodifiable.  If you want only the top level to be
439 Readonly, use the alternate C<Scalar1>, C<Array1> and C<Hash1>
440 functions.
441
442 Please note that most users of Readonly will also want to install a
443 companion module Readonly::XS.  See the L</CONS> section below for more
444 details.
445
446 =head1 COMPARISON WITH "use constant"
447
448 Perl provides a facility for creating constant values, via the "use
449 constant" pragma.  There are several problems with this pragma.
450
451 =over 2
452
453 =item *
454
455 The constants created have no leading $ or @ character.
456
457 =item *
458
459 These constants cannot be interpolated into strings.
460
461 =item *
462
463 Syntax can get dicey sometimes.  For example:
464
465  use constant CARRAY => (2, 3, 5, 7, 11, 13);
466  $a_prime = CARRAY[2];        # wrong!
467  $a_prime = (CARRAY)[2];      # right -- MUST use parentheses
468
469 =item *
470
471 You have to be very careful in places where barewords are allowed.
472 For example:
473
474  use constant SOME_KEY => 'key';
475  %hash = (key => 'value', other_key => 'other_value');
476  $some_value = $hash{SOME_KEY};        # wrong!
477  $some_value = $hash{+SOME_KEY};       # right
478
479 (who thinks to use a unary plus when using a hash?)
480
481 =item *
482
483 C<use constant> works for scalars and arrays, not hashes.
484
485 =item *
486
487 These constants are global ot the package in which they're declared;
488 cannot be lexically scoped.
489
490 =item *
491
492 Works only at compile time.
493
494 =item *
495
496 Can be overridden:
497
498  use constant PI => 3.14159;
499  ...
500  use constant PI => 2.71828;
501
502 (this does generate a warning, however, if you have warnings enabled).
503
504 =item *
505
506 It is very difficult to make and use deep structures (complex data
507 structures) with C<use constant>.
508
509 =back
510
511 =head1 COMPARISON WITH TYPEGLOB CONSTANTS
512
513 Another popular way to create read-only scalars is to modify the symbol
514 table entry for the variable by using a typeglob:
515
516  *a = \'value';
517
518 This works fine, but it only works for global variables ("my"
519 variables have no symbol table entry).  Also, the following similar
520 constructs do B<not> work:
521
522  *a = [1, 2, 3];      # Does NOT create a read-only array
523  *a = { a => 'A'};    # Does NOT create a read-only hash
524
525 =head1 PROS
526
527 Readonly.pm, on the other hand, will work with global variables and
528 with lexical ("my") variables.  It will create scalars, arrays, or
529 hashes, all of which look and work like normal, read-write Perl
530 variables.  You can use them in scalar context, in list context; you
531 can take references to them, pass them to functions, anything.
532
533 Readonly.pm also works well with complex data structures, allowing you
534 to tag the whole structure as nonmodifiable, or just the top level.
535
536 Also, Readonly variables may not be reassigned.  The following code
537 will die:
538
539  Readonly::Scalar $pi => 3.14159;
540  ...
541  Readonly::Scalar $pi => 2.71828;
542
543 =head1 CONS
544
545 Readonly.pm does impose a performance penalty.  It's pretty slow.  How
546 slow?  Run the C<benchmark.pl> script that comes with Readonly.  On my
547 test system, "use constant", typeglob constants, and regular
548 read/write Perl variables were all about the same speed, and
549 Readonly.pm constants were about 1/20 the speed.
550
551 However, there is relief.  There is a companion module available,
552 Readonly::XS.  If it is installed on your system, Readonly.pm uses it
553 to make read-only scalars much faster.  With Readonly::XS, Readonly
554 scalars are as fast as the other types of variables.  Readonly arrays
555 and hashes will still be relatively slow.  But it's likely that most
556 of your Readonly variables will be scalars.
557
558 If you can't use Readonly::XS (for example, if you don't have a C
559 compiler, or your perl is statically linked and you don't want to
560 re-link it), you have to decide whether the benefits of Readonly
561 variables outweigh the speed issue. For most configuration variables
562 (and other things that Readonly is likely to be useful for), the speed
563 issue is probably not really a big problem.  But benchmark your
564 program if it might be.  If it turns out to be a problem, you may
565 still want to use Readonly.pm during development, to catch changes to
566 variables that should not be changed, and then remove it for
567 production:
568
569  # For testing:
570  Readonly::Scalar  $Foo_Directory => '/usr/local/foo';
571  Readonly::Scalar  $Bar_Directory => '/usr/local/bar';
572  # $Foo_Directory = '/usr/local/foo';
573  # $Bar_Directory = '/usr/local/bar';
574
575  # For production:
576  # Readonly::Scalar  $Foo_Directory => '/usr/local/foo';
577  # Readonly::Scalar  $Bar_Directory => '/usr/local/bar';
578  $Foo_Directory = '/usr/local/foo';
579  $Bar_Directory = '/usr/local/bar';
580
581
582 =head1 FUNCTIONS
583
584 =over 4
585
586 =item Readonly::Scalar $var => $value;
587
588 Creates a nonmodifiable scalar, C<$var>, and assigns a value of
589 C<$value> to it.  Thereafter, its value may not be changed.  Any
590 attempt to modify the value will cause your program to die.
591
592 A value I<must> be supplied.  If you want the variable to have
593 C<undef> as its value, you must specify C<undef>.
594
595 If C<$value> is a reference to a scalar, array, or hash, then this
596 function will mark the scalar, array, or hash it points to as being
597 Readonly as well, and it will recursively traverse the structure,
598 marking the whole thing as Readonly.  Usually, this is what you want.
599 However, if you want only the C<$value> marked as Readonly, use
600 C<Scalar1>.
601
602 If $var is already a Readonly variable, the program will die with
603 an error about reassigning Readonly variables.
604
605 =item Readonly::Array @arr => (value, value, ...);
606
607 Creates a nonmodifiable array, C<@arr>, and assigns the specified list
608 of values to it.  Thereafter, none of its values may be changed; the
609 array may not be lengthened or shortened or spliced.  Any attempt to
610 do so will cause your program to die.
611
612 If any of the values passed is a reference to a scalar, array, or hash,
613 then this function will mark the scalar, array, or hash it points to as
614 being Readonly as well, and it will recursively traverse the structure,
615 marking the whole thing as Readonly.  Usually, this is what you want.
616 However, if you want only the hash C<%@arr> itself marked as Readonly,
617 use C<Array1>.
618
619 If @arr is already a Readonly variable, the program will die with
620 an error about reassigning Readonly variables.
621
622 =item Readonly::Hash %h => (key => value, key => value, ...);
623
624 =item Readonly::Hash %h => {key => value, key => value, ...};
625
626 Creates a nonmodifiable hash, C<%h>, and assigns the specified keys
627 and values to it.  Thereafter, its keys or values may not be changed.
628 Any attempt to do so will cause your program to die.
629
630 A list of keys and values may be specified (with parentheses in the
631 synopsis above), or a hash reference may be specified (curly braces in
632 the synopsis above).  If a list is specified, it must have an even
633 number of elements, or the function will die.
634
635 If any of the values is a reference to a scalar, array, or hash, then
636 this function will mark the scalar, array, or hash it points to as
637 being Readonly as well, and it will recursively traverse the
638 structure, marking the whole thing as Readonly.  Usually, this is what
639 you want.  However, if you want only the hash C<%h> itself marked as
640 Readonly, use C<Hash1>.
641
642 If %h is already a Readonly variable, the program will die with
643 an error about reassigning Readonly variables.
644
645 =item Readonly $var => $value;
646
647 =item Readonly @arr => (value, value, ...);
648
649 =item Readonly %h => (key => value, ...);
650
651 =item Readonly %h => {key => value, ...};
652
653 The C<Readonly> function is an alternate to the C<Scalar>, C<Array>,
654 and C<Hash> functions.  It has the advantage (if you consider it an
655 advantage) of being one function.  That may make your program look
656 neater, if you're initializing a whole bunch of constants at once.
657 You may or may not prefer this uniform style.
658
659 It has the disadvantage of having a slightly different syntax for
660 versions of Perl prior to 5.8.  For earlier versions, you must supply
661 a backslash, because it requires a reference as the first parameter.
662
663   Readonly \$var => $value;
664   Readonly \@arr => (value, value, ...);
665   Readonly \%h => (key => value, ...);
666   Readonly \%h => {key => value, ...};
667
668 You may or may not consider this ugly.
669
670 =item Readonly::Scalar1 $var => $value;
671
672 =item Readonly::Array1 @arr => (value, value, ...);
673
674 =item Readonly::Hash1 %h => (key => value, key => value, ...);
675
676 =item Readonly::Hash1 %h => {key => value, key => value, ...};
677
678 These alternate functions create shallow Readonly variables, instead
679 of deep ones.  For example:
680
681  Readonly::Array1 @shal => (1, 2, {perl=>'Rules', java=>'Bites'}, 4, 5);
682  Readonly::Array  @deep => (1, 2, {perl=>'Rules', java=>'Bites'}, 4, 5);
683
684  $shal[1] = 7;           # error
685  $shal[2]{APL}='Weird';  # Allowed! since the hash isn't Readonly
686  $deep[1] = 7;           # error
687  $deep[2]{APL}='Weird';  # error, since the hash is Readonly
688
689
690 =back
691
692
693 =head1 EXAMPLES
694
695  # SCALARS:
696
697  # A plain old read-only value
698  Readonly::Scalar $a => "A string value";
699
700  # The value need not be a compile-time constant:
701  Readonly::Scalar $a => $computed_value;
702
703
704  # ARRAYS:
705
706  # A read-only array:
707  Readonly::Array @a => (1, 2, 3, 4);
708
709  # The parentheses are optional:
710  Readonly::Array @a => 1, 2, 3, 4;
711
712  # You can use Perl's built-in array quoting syntax:
713  Readonly::Array @a => qw/1 2 3 4/;
714
715  # You can initialize a read-only array from a variable one:
716  Readonly::Array @a => @computed_values;
717
718  # A read-only array can be empty, too:
719  Readonly::Array @a => ();
720  Readonly::Array @a;        # equivalent
721
722
723  # HASHES
724
725  # Typical usage:
726  Readonly::Hash %a => (key1 => 'value1', key2 => 'value2');
727
728  # A read-only hash can be initialized from a variable one:
729  Readonly::Hash %a => %computed_values;
730
731  # A read-only hash can be empty:
732  Readonly::Hash %a => ();
733  Readonly::Hash %a;        # equivalent
734
735  # If you pass an odd number of values, the program will die:
736  Readonly::Hash %a => (key1 => 'value1', "value2");
737      --> dies with "May not store an odd number of values in a hash"
738
739
740 =head1 EXPORTS
741
742 By default, this module exports the following symbol into the calling
743 program's namespace:
744
745  Readonly
746
747 The following symbols are available for import into your program, if
748 you like:
749
750  Scalar  Scalar1
751  Array   Array1
752  Hash    Hash1
753
754
755 =head1 REQUIREMENTS
756
757  Perl 5.000
758  Carp.pm (included with Perl)
759  Exporter.pm (included with Perl)
760
761  Readonly::XS is recommended but not required.
762
763 =head1 ACKNOWLEDGEMENTS
764
765 Thanks to Slaven Rezic for the idea of one common function
766 (Readonly) for all three types of variables (13 April 2002).
767
768 Thanks to Ernest Lergon for the idea (and initial code) for
769 deeply-Readonly data structures (21 May 2002).
770
771 Thanks to Damian Conway for the idea (and code) for making the
772 Readonly function work a lot smoother under perl 5.8+.
773
774
775 =head1 AUTHOR / COPYRIGHT
776
777 Eric J. Roode, roode@cpan.org
778
779 Copyright (c) 2001-2004 by Eric J. Roode. All Rights Reserved.  This
780 module is free software; you can redistribute it and/or modify it under
781 the same terms as Perl itself.
782
783 If you have suggestions for improvement, please drop me a line.  If
784 you make improvements to this software, I ask that you please send me
785 a copy of your changes. Thanks.
786
787 Readonly.pm is made from 100% recycled electrons.  No animals were
788 harmed during the development and testing of this module.  Not sold
789 in stores!  Readonly::XS sold separately.  Void where prohibited.
790
791 =cut
792
793 =begin gpg
794
795 -----BEGIN PGP SIGNATURE-----
796 Version: GnuPG v1.2.4 (MingW32)
797
798 iD8DBQFAhaGCY96i4h5M0egRAg++AJ0ar4ncojbOp0OOc2wo+E/1cBn5cQCg9eP9
799 qTzAC87PuyKB+vrcRykrDbo=
800 =39Ny
801 -----END PGP SIGNATURE-----
802
803 =cut
Note: See TracBrowser for help on using the browser.

Unless explicitly stated otherwise all content © University of Southampton 2007.