4

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 = {}; 
Tanktalus
  • 21,664
  • 5
  • 41
  • 68
  • 1
    Autovivification is the automatic creation of a variable when `undef` is dereferenced. For example, it makes `$task->{parent_id}` equivalent to `( $task //= {} )->{parent_id}`. But there's no dereference in `Dumper($task);`. – ikegami Feb 05 '19 at 20:36

1 Answers1

5
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);
Tanktalus
  • 21,664
  • 5
  • 41
  • 68