1Tie::Hash::ReadonlyStacUks(e3r)Contributed Perl DocumentTaitei:o:nHash::ReadonlyStack(3)
2
3
4
6 Tie::Hash::ReadonlyStack - Treat multiple hashes as a single hash and
7 do not modify original hashes when assigning values
8
10 This document describes Tie::Hash::ReadonlyStack version 0.2
11
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
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
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
248 Throws no errors or warnings itself
249
251 Tie::Hash::ReadonlyStack requires no configuration files or environment
252 variables.
253
255 None.
256
258 None reported.
259
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
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
276 Tie::Proxy::Hash, perltie
277
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
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
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.32.0 2020-07-28 Tie::Hash::ReadonlyStack(3)