I think this question is a little more subtle because of the way Win32::TieRegistry uses tied hashes as an interface. It's not immediately obvious what happens if multi-level hash keys are used. You can do chaining as if it were a HoH structure, but the documentation seems to imply that the "autovivification" is temporary and is only reflected in the Perl data structure, not the underlying registry.
From the Pod:
$tip18= $Registry->{"LMachine/Software/Microsoft/"}->
{"Windows/CurrentVersion/Explorer/Tips/"}->{"/18"};
Like above, this creates intermediate key objects then uses them t
+o access other data. Once this statement finishes, the intermediate k
+ey objects are destroyed. Several handles into the Registry are opene
+d and closed by this statement so it is less efficient but there are
+times when this will be useful.
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
| [reply] [d/l] |
Yes, after I posted, I realized that I hadn't addressed the multi-level hash issue. I didn't pursue it because I was sure it didn't matter. However, I did some testing and was shocked to find that Perl's autovivification can trigger a tied object's STORE method. I guess I shouldn't have been shocked.
So, yes, you can access a key in an unusual way and cause things to be created, unfortunately. I've long (very long) wanted a pragma to disable autovivification and this makes me want it that much more.
However, if you just attempt to fetch a single item (key or value) from the registry with Win32::TieRegistry, then it won't create anything in the registry.
Trying to fetch something that doesn't exist and using it directly in an lvalue context (such as chaining another fetch onto it) can cause stuff to be created. And, as I've noted elsewhere, exists has no magic powers for preventing such autovivification. It can prevent a sneaky lvalue context from suprising you (exactly the same as scalar or any number of other things can do).
But simply avoiding an lvalue context is also enough. For example:
my $key= $Registry->{"..."};
Or even:
if( $Registry->{"..."} ) {
is never going to create anything in the registry.
Update: I should add an option to the module to die if you try to create by assigning an empty hash ref because that would prevent autovivification.
| [reply] [d/l] [select] |