Reputation: 1138
Does Perl real auto-vivifies key when the unexisting key is assigned to a variable?
I have this code :
my $variable = $self->{database}->{'my_key'}[0];
The variable $self->{database}->{'my_key'}[0]
is undefined in my hash, but if I print a Dumper after the assignment, I'm surprised that the my_key
is created.
I know the functionality for this case :
use Data::Dumper;
my $array;
$array->[3] = 'Buster'; # autovivification
print Dumper( $array );
This will give me the results :
$VAR1 = [
undef,
undef,
undef,
'Buster'
];
But never expected to work the other way arround, where :
my $weird_autovivification = $array->[3];
will also vivify $array->[3]
.
Upvotes: 1
Views: 356
Reputation: 386621
Does Perl real auto-vivifies key when the unexisting key is assigned to a variable?
Perl autovivifies variables (including array elements and hash values) when they are dereferenced.
$foo->{bar} [ $foo dereferenced as a hash ] ≡ ( $foo //= {} )->{bar}
$foo->[3] [ $foo dereferenced as an array ] ≡ ( $foo //= [] )->[3]
$$foo [ $foo dereferenced as a scalar ] ≡ ${ $foo //= do { my \$anon } }
etc
This means that
$self->{database}->{'my_key'}[0]
autovivifies
$self
(to a hash ref if undefined)$self->{database}
(to a hash ref if undefined)$self->{database}->{'my_key'}
(to an array ref if undefined)but not
$self->{database}->{'my_key'}[0]
(since it wasn't dereferenced)But never expected to work the other way arround, where :
my $weird_autovivification = $array->[3];
will also vivify$array->[3]
.
Not quite. It autovivifies $array
, the variable being dereferenced. Nothing was assigned to $array->[3]
since it wasn't dereferenced.
Tip: The autovivification pragma can be used to control when autovivification occurs.
Upvotes: 8
Reputation: 69314
But never expected to work the other way arround, where :
my $weird_autovivification = $array->[3];
will also vivificate$array[3]
.
That's not how it works.
$ perl -MData::Dumper -E'$foo=$array->[3]; say Dumper $array'
$VAR1 = [];
Executing that code has turned $array
into an array reference (where, previously, it would have been undefined), but it hasn't set $array->[3]
to anything.
If we add another level of look-up, we get slightly different behaviour:
$ perl -MData::Dumper -E'$foo=$array->[0][3]; say Dumper $array'
$VAR1 = [
[]
];
Here, Perl has created $array->[0]
and set it to a reference to an empty array, but it hasn't affected $array->[0][3]
.
In general, as you're going through a chain of look-ups in a complex data structure, Perl will autovivify all but the last link in the chain. When you think about it, that makes a lot of sense. Perl needs to autovivify one link in the chain so that it can check the existence of the next one.
Upvotes: 11