On Wed, 13 May 2009, Steve Hay wrote:
> Jan Dubois wrote on 2008-12-08:
>> If you run `perl -eprint$ENV{PERLFOO}` it will first check for an
>> environment variable called PERLFOO, but if it isn't found, it will
>> check first HKCU\Software\Perl and then HKLM\Software\Perl for a
>> PERLFOO entry and return that. Only when none of them are set will
>> you get undef.
[...]
> I just stumbled across this while looking back through old emails.
>
> I wasn't aware of this "feature", and when I tried it myself it
> didn't work.
Not sure if this discussion is on-topic on the PAR list; maybe it should
move to p5p if we continue this any further.
> It turns out that there is a way to turn it off for environment
> variables accessed via %ENV: build your perl without PERL_IMPLICIT_SYS
> (which is how mine is built, hence my initial confusion).
>
> In win32.h, DYNAMIC_ENV_FETCH is only #defined if PERL_IMPLICIT_SYS is
> #defined. When DYNAMIC_ENV_FETCH is #defined, hv_common() does a
> dynamic lookup in the environment using PerlEnv_ENVgetenv_len(), which
> winds up in win32_getenv(), which looks up PERL* variables in HKCU or
> HKLM if they weren't in the environment. But without
> DYNAMIC_ENV_FETCH, hv_common() only looks in the %ENV hash that it
> already has.
You should be able to -DDYNAMIC_ENV_FETCH even on a non-
PERL_IMPLICIT_SYS configuration if you really want to get this
functionality.
But I think DYNAMIC_ENV_FETCH is really meant for embedded interpreters,
like Perl running inside a web server, where each new request will
show up with a different set of environment variables, so you cannot
rely on the cached values in %ENV. I assume mod_perl works around this
by updating %ENV before calling back into Perl, but that is potentially
slower than dynamically fetching the values on demand.
> However, all the special PERL* environment variables used by perl's
> own C code (e.g. PERL5LIB, PERL5OPT, PERL_UNICODE, PERL_HASH_SEED,
> etc) seem to be accessed by calls to PerlEnv_getenv(), which does
> still go through win32_getenv(), so they are looked up the registry
> even when PERL_IMPLICIT_SYS is not defined.
I think this is again done for embedding Perl into Windows services,
where you don't have good control over the environment variables that
the service sees without having to reboot the machine for each change.
An example would again be a web server like IIS. Services are started
by the service control manager and will inherit their environement
from the SCM, which is only initialized once during the boot process.
This may have changed in later Windows versions though; I don't know.
> Seems nasty to me: without PERL_IMPLICIT_SYS, anything calling
> getenv() will check the registry too, but anything using %ENV won't!
> So if you set PERL5LIB in the registry then perl.c sees it when it
> calls PerlEnv_getenv("PERL5LIB") but the perl script you're running
> won't see it when it looks for $ENV{PERL5LIB}!
I'm tempted to suggest that the whole %ENV lookup in the registry is
a misfeature and should be removed in Perl 5.12 or 5.14. But that
discussion really should happen on P5P.
Cheers,
-Jan