Search code examples
perlautovivification

perl autovivification when calling subroutine


Why auto-vivification does not work when calling procedures? Is there a way to prohibit it in this case too?

#!/usr/bin/env perl
no autovivification;
use Data::Dumper;

sub testsub { }

my $task;
print Dumper($task);    # $VAR1 = undef;
my $a = $task->{parent_id};
print Dumper($task);    # $VAR1 = undef;
my $b = testsub($task->{parent_id});
print Dumper($task);    # $VAR1 = {}; 

Solution

  • my $task
    print Dumper($task)
    

    At this point, perl has no idea what to autovivify. It passes an LVALUE reference of $task to Dumper, which does nothing with that reference, so nothing happens

    my $a = $task->{parent_id}
    

    Because this is a copy, it's treated as an RVALUE. Thus no vivification required.

    my $b = testsub($task->{parent_id})
    

    To populate @_ properly with LVALUE references, perl now has to create the hash so that it can pass in the reference properly.

    To avoid doing so, you could pass in a reference to $task, and then access parent_id inside when necessary:

    sub testsub { my $task_ref = shift; if (something) { $$task_ref->{parent_id} = 3 } }
    my $b = testsub(\$task);