1Tie::Hash::ReadonlyStacUks(e3r)Contributed Perl DocumentTaitei:o:nHash::ReadonlyStack(3)
2
3
4

NAME

6       Tie::Hash::ReadonlyStack - Treat multiple hashes as a single hash and
7       do not modify original hashes when assigning values
8

VERSION

10       This document describes Tie::Hash::ReadonlyStack version 0.2
11

SYNOPSIS

13           use Tie::Hash::ReadonlyStack;
14
15           # %defaults could be a readonly hash, maybe from something like this: Readonly::Hash    my %defaults => ( ... );
16           # or maybe you just want to modify some values without blowing away a global default
17           my $tie_obj = tie my %config, 'Tie::Hash::ReadonlyStack', \%defaults;
18
19           # load up any server specific configuration we have
20           $tie_obj->add_lookup_override_hash('local', \%server_specific_hash);
21
22           # when we determine the user:
23           $tie_obj->add_lookup_override_hash('user', \%user_specific_hash);
24
25           # when we go to run a given context:
26           $tie_obj->add_lookup_fallback_hash('context', \%context_specific_hash);
27
28           # look for 'frobnigate' in  %user_specific_hash, %server_specific_hash, %defaults, %context_specific_hash
29           # returning the value of the first found, lets say it's current value is 1 which is inside %server_specific_hash
30           if ($config{'frobnigate'}) {
31               $config{'frobnigate'} += 5; # %server_specific_hash (actually, all of the hash's above) remains unchanged
32               print $config{'frobnigate'};
33               # this prints '6'  ,
34               # the tied hash '%config' holds the new value, the value is unchanged in the hashes making up %config
35           }
36
37           # context is ending so clean up:
38           $tie_obj->delete_lookup_hash('context');
39
40           ...
41
42           undef $tie_obj; # untie() caveat!
43           untie %config
44

DESCRIPTION

46       The tie via this module has 2 main behaviors.
47
48       First, it treats a stack of hashes as a single unit similar to
49       Tie::Proxy::Hash (but without the "translation" mechanism and some
50       other differences)
51
52       This allows you to have your main hash and then assign hashes to look
53       for the given key in either before or after the main hash.
54
55       See the "SYNOPSIS" for an example of that.
56
57       Second, it allows you to use hashes that are readonly in said stack
58       without fatal errors.
59
60       For example, say you you have a hash created via, ironically enough,
61       Readonly. If you try to assign to it:
62
63          Readonly::Hash    my %readonly => ( ... );
64          $readonly{'key'} = 'value'; # throws "Modification of a read-only value attempted at ..."
65
66       or say you have a GDBM_File file tied in readonly mode:
67
68         tie my %gdbm, 'GDBM_File', 'data.gdbm', &GDBM_READER, 0640;
69         $gdbm{'key'} = 'value'; # throws "gdbm store returned -1, errno 0, key "key" at ..."
70         print $gdbm{'key'}; # never gets here
71         print $gdbm{'abc'};
72
73       You could wrap such assignments in an eval but not only is that
74       cluttered the value is unchanged (sort of what "readonly" means ;p)
75
76       Putting that hash into a Tie::Hash::ReadonlyStack hash allows you to
77       assign new values without modifying the hash it came from.
78
79          tie my %gdbm, 'GDBM_File', 'data.gdbm', &GDBM_READER, 0640;
80          tie my %data, 'Tie::Hash::ReadonlyStack', \%gdbm;
81          $data{'key'} = 'value';
82          print $data{'key'}; # prints 'value'
83          print $data{'abc'}; # prints the value of 'abc' from the database
84
85       Besides the fact that storing a new value won't trigger fatal errors on
86       various sorts of readonly type hashes it also has another benefit:
87
88       Sometimes a hash keys's value is used to calculate a new value and the
89       new value is re-stored as a cacheing mechanism.
90
91       For example, with a Locale::Maketext Lexicon hash: a key is looked up,
92       compiled into an internal form, and re-stored as a reference, typically
93       a SCALAR or CODE. Template::ToolKit can do similar behavior. If your
94       tied hash stored the new value in your database then the next time it
95       is used, you'd probably get something like 'SCALAR(0x800ab0)' or
96       'CODE(0x800ab0)' instead of the string you expected.
97
98       In short, keeping all new values internally as part of the
99       'Tie::Hash::ReadonlyStack' is a good thing because it:
100
101       •   keeps the orignal hashes unmodified (i.e. does not stomp on things
102           you might not want stomped on)
103
104       •   will make readonly hashes not fatal when values are changed
105
106       •   allow values to be changed for local pruposes (i.e. as part of a
107           calculate-then-cache mechanism)
108

INTERFACE

110       This is just a normal tie(). The only argument after the name space is
111       the single "main" hash.
112
113          tie my %hash, ' Tie::Hash::ReadonlyStack', \%main_hash;
114
115       Others can be added or removed via the methods outlined below.
116
117   tie object methods
118       You get the tie object as the return value of tie() and tied()
119
120           my $tie_obj = tie my %hash, 'Tie::Hash::ReadonlyStack', \%main_hash;
121
122       or
123
124          tie my %hash, ' Tie::Hash::ReadonlyStack', \%main_hash;
125          ...
126          my $tie_obj = tied(%hash);
127
128       If you use the tie object make sure you clean it up before untie()
129
130       (i.e. this is the untie() caveat mentioned in pretty much every tie
131       related document, see "OBLIGATORY UNTIE CAVEAT")
132
133          undef $tie_obj; # untie() caveat, undef any references before you untie it!
134          untie %hash;
135
136       add_lookup_override_hash()
137
138       Adds the hash to the stack before the "main" one.
139
140          $tie_obj->add_lookup_override_hash('identifier',\%hash);
141
142       It will not add the "main" hash or an already existing one. If you want
143       to replace a hash you must del_lookup_hash() first.
144
145       If %hash is not tied then this happens:
146
147          $tie_obj->clear_compiled_cache(keys %hash)
148
149       If it is tied (since keys() could possibly have a lot of wasted
150       overhead *) then the new hash is checked for the existence of each
151       compiled key which is deleted from the cache if it exists.
152
153       If this behavior is undesireable with your tied hash you can call
154       "add_lookup_override_hash_without_clearing_cache()" and handle the
155       cache however you need to via "clear_compiled_cache()"
156
157       * Imagine it is tied to a DB_File with ten million keys. keys() and
158       each() would be very expensive for no advantage...
159
160       add_lookup_override_hash_without_clearing_cache()
161
162       Same as add_lookup_override_hash() except with out the cache clearing
163       behavior.
164
165       add_lookup_fallback_hash()
166
167       Adds the hash to the stack after the "main" one.
168
169          $tie_obj->add_lookup_fallback_hash('identifier',\%hash);
170
171       It will not add the "main" hash or an already existing one. If you want
172       to replace a hash you must del_lookup_hash() first.
173
174       del_lookup_hash()
175
176       Remove the hash from the stack and remove any of its values that are in
177       the cache
178
179          $tie_obj->del_lookup_hash('identifier')
180
181       Returns false if you try to remove the "main" hash.
182
183       By default it won't do an exists() check, this is good because it will
184       clean up any dangling bits leftover by bad manual intervention (but you
185       wouldn't do that would you ;p).
186
187       To make it return false when the hash being delted does not exist give
188       it a second true argument:
189
190           # assuming $only_if_exists is true:
191
192           if (!$tie_obj->del_lookup_hash('identifier', $only_if_exists)) {
193               print "The given hash isn't part of the stack, that sure is weird...";
194           }
195           else {
196               print "The given hash has been removed from the stack";
197           }
198
199       clear_compiled_cache()
200
201       This method empties the cache or un-caches a given list of keys.
202
203           $tie_obj->clear_compiled_cache(); # remove all cached values
204
205       The 'no argument' form returns 1.
206
207           $tie_obj->clear_compiled_cache('foo','bar'); # remove 'foo' and 'bar' from the cache
208
209       The 'list of keys arguments' form returns the number of keys actually
210       deleted or false if none of the given keys existed (and hence nothing
211       was deleted)
212
213       get_keys_not_in_stack()
214
215       This returns a list of keys that were used but were not found in any of
216       the hashes in the stack.
217
218       That happens when you assign a value to a key that does not exist in
219       any of the hashes in the stack:
220
221          $hash{'new_key'} = 42; # $tie_obj->get_keys_not_in_stack() would now include 'new_key'
222
223          delete $hash{'new_key'}; # $tie_obj->get_keys_not_in_stack() would no longer include 'new_key'
224
225   hash behavior
226       fetching a value (e.g. using the $hash{'key'} or exists()) will:
227
228       1 look in the cache to see if we have it already
229       2 if the key is not in the cache it looks for the key in each hash in
230       the stack of hashes in the proper order
231       3 if we're fetching the value: in the first hash it exists in it will
232       cache it and use that
233
234       Assigning a value will add the key and fetched value to the cache (i.e.
235       not to any of the hashes in the stack)
236
237       each(), keys(), values(), etc operate on tha cache of values you've
238       accessed and assigned.
239
240       That means that if you are tied to a database with ten million keys via
241       a hash that gets them from the DB on demand instead of loading them all
242       up at once and have only referenced 5 then your working hash has 5 keys
243
244       If you delete() a key it deletes it from the cache but not from hashes
245       in the stack.
246

DIAGNOSTICS

248       Throws no errors or warnings itself
249

CONFIGURATION AND ENVIRONMENT

251       Tie::Hash::ReadonlyStack requires no configuration files or environment
252       variables.
253

DEPENDENCIES

255       None.
256

INCOMPATIBILITIES

258       None reported.
259

BUGS AND LIMITATIONS

261       No bugs have been reported.
262
263       Please report any bugs or feature requests to
264       "bug-tie-hash-readonlystack@rt.cpan.org", or through the web interface
265       at <http://rt.cpan.org>.
266

OBLIGATORY UNTIE CAVEAT

268       See "The "untie" Gotcha " in perltie or "The "untie" Gotcha" in perltie
269       depending on if the perdoc you get sent to has the broken-by-extra-
270       space 'The untie Gotcha' header
271
272       Note that this module doesn't (currently) define a destructor so we
273       should be fine.
274

SEE ALSO

276       Tie::Proxy::Hash, perltie
277

TODO

279       review for efficiency improvements, especially memory
280
281       ? consider mechanism to mark certain hashes as "update this hash's
282       value instead of the cache" ?
283
284       review for additional tests, perhaps of object's structure and state at
285       various points ?
286

AUTHOR

288       Daniel Muey  "<http://drmuey.com/cpan_contact.pl>"
289
291       Copyright (c) 2009, Daniel Muey "<http://drmuey.com/cpan_contact.pl>".
292       All rights reserved.
293
294       This module is free software; you can redistribute it and/or modify it
295       under the same terms as Perl itself. See perlartistic.
296

DISCLAIMER OF WARRANTY

298       BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
299       FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
300       WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
301       PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
302       EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
303       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
304       ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
305       YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
306       NECESSARY SERVICING, REPAIR, OR CORRECTION.
307
308       IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
309       WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
310       REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
311       TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
312       CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
313       SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
314       RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
315       FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
316       SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
317       DAMAGES.
318
319
320
321perl v5.34.0                      2021-07-23       Tie::Hash::ReadonlyStack(3)
Impressum