]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - config/mpfire/perl/Readonly.pm
Finalized core13 and redirector fixes
[people/pmueller/ipfire-2.x.git] / config / mpfire / perl / Readonly.pm
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