Others already pointed you to the "how", namely Perl's autovivification
But it seems nobody explained "why".
It's DWIM.
If you try the same thing in JS you get an error.
in the browser's console (F12)
> a = { b : {} };
> f = a["b"]["c"]["d"]["e"]
Uncaught TypeError: Cannot read properties of undefined (reading 'd'
+)
at <anonymous>:1:16
> f = a.b.c.d.e
Uncaught TypeError: Cannot read properties of undefined (reading 'd'
+)
at <anonymous>:1:11
Assigning to a deeply nested path is even more a PITA in those languages
> a["b"]["c"]["d"]["e"] ="X"
Uncaught TypeError: Cannot read properties of undefined (reading 'd'
+)
at <anonymous>:1:12
> a.b.c.d.e = "X"
Uncaught TypeError: Cannot read properties of undefined (reading 'd')
at <anonymous>:1:7
You'll need a loop to build each level step by step.
But Perl does DWIM by creating accessed levels on the fly.
> perl -de0
...
DB<1> $a->{b}{c}{d}="X"
DB<2> x $a
0 HASH(0x32445c8)
'b' => HASH(0x3244220)
'c' => HASH(0x3244130)
'd' => 'X'
DB<3>
Many paint this as bug, because it's different to other languages.
I disagree, it's a case where you can't make an omelet without breaking an egg somewhere.
And I profit from this far more often than I stumble over it.
It should be be better explained and motivated though.
meta
There is no autovivification to disable this on demand
I personally think a syntactic solution with a no-autovivification operator might have been better.
Alas there are not many characters left in the alphabet, and I'm not sure such a syntax could work:
$a->{b}:{c}{d} # should not vivify beneath b
FWIW there is also Data::Diver (and other similar modules) on CPAN, which could also be core.
update
BTW: Contrary to the title, you don't need the arrow operator to see this effect.
update
I'd love to see other or even better motivations for "Autovivification" discussed.
|