in reply to Re^2: Win32 GetEnvironmentVariables?
in thread Win32 GetEnvironmentVariables?

but %ENV is magical
%ENV appears to be magical only under shells where the lookup and expansion of environmental variables is a case-insensitve operation.

$ set comspec ComSpec=C:\WINDOWS\system32\cmd.exe $ echo %comspec% C:\WINDOWS\system32\cmd.exe $ echo %COMSPEC% C:\WINDOWS\system32\cmd.exe $ perl -le "print 'comspec : ', $ENV{comspec}" comspec : C:\WINDOWS\system32\cmd.exe $ perl -le "print 'COMSPEC : ', $ENV{COMSPEC}" COMSPEC : C:\WINDOWS\system32\cmd.exe
On systems (shells rather) where there is a distinction between the case-sensitivity of Env. Vars, %ENV behaves rather normally like a hash should.
$ set | grep -i ^shell shell /bin/tcsh $ echo $shell /bin/tcsh $ echo $SHELL $ perl -le 'print "shell : ", $ENV{shell}' shell : $ perl -le 'print "SHELL : ", $ENV{SHELL}' SHELL : /bin/bash
It's likely %ENV is tied (I am guessing) or has mechanism similar to tie associated with it to pass lookups to an underlying system call. It should be noted that not all environmental varaibles are populated into %ENV and in other cases, the values of %ENV contradict those of the shell (as shown above). Don't rely too heavily on information or its validity presented to you in %ENV;

There is a difference between %ENV and Win32::ExpandEnvironmentStrings.

%ENV holds literals (just like the shell, in most cases atleast), Win32::ExpandEnvironmentStrings() tests the expansion of a literal in the win32 environment and returns it after substituting values defined for the current user.
$ set var var=%OS% $ perl -MWin32 -e "print $ENV{var} .= ' evaled' , ' => ', Win32::Expa +ndEnvironmentStrings($ENV{var})" %OS% evaled => Windows_NT evaled
For the purposes of delayed expansion in the environment, Win32::ExpandEnvironmentStrings() then takes a literal string of the form !Foo! rather than %Foo%.
$ set var=Foo $ set var var=Foo $ set var=Bar & perl -MWin32 -e "print Win32::ExpandEnvironmentStrings +('%var%')" Foo $ set var var=Bar $ set var=Baz & perl -MWin32 -e "print Win32::ExpandEnvironmentStrings +('!var!')" Baz $ set var var=Baz

Replies are listed 'Best First'.
Re^4: Win32 GetEnvironmentVariables?
by ikegami (Patriarch) on Nov 12, 2006 at 22:46 UTC

    It's likely %ENV is tied (I am guessing) or has mechanism similar to tie associated with it to pass lookups to an underlying system call

    That mechanism is called "magic". Tied variables are a specific kind (MG_TYPE) of magical variables.

    %ENV appears to be magical only under shells where the lookup and expansion of environmental variables is a case-insensitve operation.

    It is my understanding that %ENV is magical on all platforms. The magic translates access to %ENV into C library calls.

    To see if %ENV is magical, run

    perl -MDevel::Peek -e 'Dump \%ENV, 1'

    On Windows, that outputs

    SV = RV(0x183a4ec) at 0x2251d8 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x225db4 SV = PVHV(0x229584) at 0x225db4 REFCNT = 2 FLAGS = (SMG,RMG,SHAREKEYS) IV = 29 NV = 0 MAGIC = 0x182a964 <---- MG_VIRTUAL = &PL_vtbl_env MG_TYPE = PERL_MAGIC_env(E) ARRAY = 0x18257cc (0:13, 1:11, 2:6, 3:2) hash quality = 102.6% KEYS = 29 FILL = 19 MAX = 31 RITER = -1 EITER = 0x0

    I don't have access to a unix machine at the moment.

    Perl probably doesn't even care whether the env vars are case-sensitive or not. That's probably handled by the C library or passed on the OS.