in reply to Autovivification sucking the life out of me

This really has nothing to do with autovivification, you never attempted to define $ENV{TMPDIR}, and $ENV{TMPDIR} never existed (through either you or autovivification, unless it was really defined as an environment variable before you enter the program) before or after.

The first argument you passed in is undef, which failed the join. Not surprisingly, comment out printf obviously will get rid of the error. Here is part of your code without that function:

use strict; use warnings; use Data::Dumper; warn sprintf "In test, at start (1): TMPDIR '%s'\n", ! exists $ENV{TMPDIR} ? '<absent>' : ! defined $ENV{TMPDIR} ? + '<undef>' : $ENV{TMPDIR}; print Dumper(@ENV{qw(TMPDIR TEMP TMP)});

Which prints:

$VAR1 = undef; $VAR2 = 'C:\\DOCUME~1\\someone\\LOCALS~1\\Temp'; $VAR3 = 'C:\\DOCUME~1\\someone\\LOCALS~1\\Temp';

Replies are listed 'Best First'.
Re^2: Autovivification sucking the life out of me
by shenme (Priest) on Oct 14, 2005 at 06:48 UTC
    I think you missed the point of the post, which is "how is the variable $ENV{TMPDIR} being autovivified?" I am not caring that the value passed into the subroutine is undefined, since the environment variable is indeed not defined. But I do care that the variable outside the subroutine changes from '<absent>' to '<undef>'.

      Update: My apologies! Forget what I have said, it was my observation was off, not yours. But it might be a better idea to demo your issue by using Data::Dumper.

      use Data::Dumper; use strict; use warnings; my %foo = ( BAZ => 1 ); sub see_args { }; print Dumper(\%foo); see_args( @foo{qw(BAR BAZ)} ); print Dumper(\%foo);

      It prints:

      $VAR1 = { 'BAZ' => 1 }; $VAR1 = { 'BAZ' => 1, 'BAR' => undef };

      Yes, autovivification is in working.

      Your observation was off. In your original post, you were confused by the fact that the $ENV{TMPDIR} "appears" to have a value as you saw it through that sprintf. No, you didn't see the value of $ENV{TMPDIR}. Your sprintf printed a constant "<absent>", not the value of $ENV{TMPDIR}.</strick>

        A simpler example perhaps:
        use strict; use warnings; my %foo = ( BAZ => 1 ); sub see_args { }; warn sprintf "at start: BAR '%s'\n", ! exists $foo{BAR} ? '<absent>' : ! defined $foo{BAR} ? '<und +ef>' : $foo{BAR}; # see_args( @foo{qw(BAR BAZ)} ); my @a = @foo{qw(BAR BAZ)}; warn sprintf "at end: BAR '%s'\n", ! exists $foo{BAR} ? '<absent>' : ! defined $foo{BAR} ? '<und +ef>' : $foo{BAR};

        Running this without the subroutine call, but rather the assignment to the array, results in output:

        at start: BAR '<absent>' at end: BAR '<absent>'
        That is, using the slice @foo{qw(BAR BAZ)} returns the values without modifying them.

        Commenting out the assignment and instead executing the subroutine call produces this output:

        at start: BAR '<absent>' at end: BAR '<undef>'
        Somehow using the slice in the call to the subroutine has modified the values in the slice, creating an undef value for the key 'BAR'. How?