]>
Commit | Line | Data |
---|---|---|
83d20a45 CS |
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 |